使用SQL Server, nodejs和bycrypt,在函数收到之前请求结束



我是nodejs的新手,我的代码遇到了一个问题。

SQL Server的文档和我在Youtube上找到的指南都以这种方式处理他们的代码,但在开始使用加密后,我注意到我的功能在请求完成后结束,尽管我使用.then()

无论如何,这是我目前为止的代码:

router.post('/login',  (req, res) => {
getLoginDetails(req.body.username, req.body.password).then(result => {
console.log(result);
res.json(result);
})
});
async function getLoginDetails(username, password) {
await pool1Connect;
try {
const request = pool1.request();
request.input('username', sql.NVarChar, username);

request.query('SELECT * FROM users WHERE username = @username', (err, result) => {        
if (err) {
return ({err: err})
}
if (result.recordset.length > 0) {
bcrypt.compare(password, result.recordset[0].user_password, (err, response) => {
if (response) {
console.log(result.recordset);
return(result.recordset);
} else {
return({message: "Wrong password or username!"})
}
})
return(result)
} else {
return({message: "user not found!"})
}
})
} catch (err) {
return err;
}
}

我尝试记录请求和函数getLoginDetails的返回值,请求日志来的更快,所以我认为它不是等待程序实际完成,我不知道为什么…

很抱歉,如果这是显而易见的,但我希望得到一些帮助!

编辑:

router.post('/login', async (req, res) => {
// res.send(getLoginDetails(req.body.username, req.body.password))
await pool1Connect
try {
const request = pool1.request();
request.input('username', sql.NVarChar, req.body.username);
request.query('SELECT * FROM users WHERE username = @username', (err, result) => {
console.log(result);
bcrypt.compare(req.body.password, result.recordset[0].user_password, (err, response) => {
if (response) {
res.send(result);
} else {
res.send('wrong password')
}

})
//res.send(result)
})
} catch (err) {
res.send(err);
}
});

这段代码可以工作,但是当我试图将它封装在一个函数中时,它仍然不能工作。

@Anatoly提到.query没有及时完成,这是有道理的,但我认为mssql.query是一个异步函数?

你的问题来自于一个错误的假设,即回调和承诺是相似的,但恰恰相反,回调并不"尊重"。承诺/异步结构

当程序到达getLoginDetails的底部时,程序执行已经分成两个分支,一个分支返回(空)结果,而另一个分支仍然忙于加密操作。

虽然async函数总是返回一个promise,但这并不包括任何可能在其中执行的未来回调。一旦节点到达函数或任何返回语句的结束,异步函数的承诺就会被解决(因此未来的回调是无意义的),你可以做的是手滚你自己的承诺,它也包含回调

router.post('/login', (req, res) => {
getLoginDetails(req.body.username, req.body.password))
.then((result)=>{
res.send(result);
})
.catch((err)=>{
res.send(err);
})
});
async function getLoginDetails(username, password) {
await pool1Connect
return new Promise( (resolve,reject)  => {
try {
const request = pool1.request();
request.input('username', sql.NVarChar, username);
request.query('SELECT * FROM users WHERE username = @username', (err, result) => {
console.log(result);
bcrypt.compare(password, result.recordset[0].user_password, (err, response) => {
if (response) {
resolve(result);
} else {
resolve('wrong password')
}
})
})
} catch (err) {
reject(err);
}
});
}

您没有返回任何结果到getLoginDetails。您可以使用request.querybcrypt.compare(如果有的话)的async版本,或者将request.query包装为new Promise((resolve, reject),如下所示:

const asyncResult = new Promise((resolve, reject) => {
request.query('SELECT ...
...
if (err) {
resolve({err: err}) // replace all return statements with resolve calls
}
...
})
const queryResult = await asyncResult;

相关内容

  • 没有找到相关文章

最新更新