如何在 Node JS 中访问查询回调之外的变量



我正在node中制作一个应用程序.js我卡在一个地方。我运行一个查询,然后我想将这些查询结果推送到一个数组中并返回该数组。问题是它不会在查询回调之外访问该数组。我的代码如下所示。

var emailsToReturn = [];
emails.forEach(( email, index ) => {
var msgId = email.message_id;
//fetch attachments against this attachment
var fetchAttachments = `SELECT * FROM email_attachments WHERE message_id='${msgId}'`;
connection.query(fetchAttachments, (err, attachmentsResult)=>{
email['attachments'] = attachmentsResult;                
emailsToReturn.push(email); // this show desired results here.
});

});
console.log(JSON.stringify(emailsToReturn, null, 4)); // this shows empty array here outside of query callback.

我知道这是范围问题,我也尝试使用global。但这也没有奏效。任何帮助将不胜感激。谢谢!

基本上这里发生的事情是emailToReturn是全局变量,可以在任何地方访问。您正在更新电子邮件返回的值,然后尝试打印它。


但真正发生的事情是 JavaScript 在后台更新 emailToReturn 的值,当该过程正在进行时,JavaScript 执行下一条指令,即控制台.log 。因此,值仍在后台更新,您转到下一条指令并打印仍然相同的变量值。

如何解决?
您可以使用 async/await (https://www.geeksforgeeks.org/using-async-await-in-node-js/(
我有使用等待。现在Javascript将等待查询的结果,然后更新数组,然后转到下一条指令。
var emailsToReturn = [];
async function functionName(emails,index){
emails.forEach(( email, index ) => {
var msgId = email.message_id;
//fetch attachments against this attachment
var fetchAttachments = `SELECT * FROM email_attachments WHERE message_id='${msgId}'`;
let attachmentsResult = await connection.query(fetchAttachments)
if(attachmentsResult.err){
console.log(err);
}else{
email['attachments'] = attachmentsResult;                
emailsToReturn.push(email); // this show desired results here.
}
});
console.log(JSON.stringify(emailsToReturn, null, 4));
//req.send(JSON.stringify(emailsToReturn, null, 4));//use to send response
}
functionName(emails,index)

基本上,由于nodejs的异步性质,您尝试执行的操作不会给您带来所需的结果。您的控制台在循环之前运行(由于数据库操作而处于异步状态(。您可以使用异步库中的瀑布方法,并在初始化"电子邮件"后尝试如下操作:

const async = require("async");
var emailsToReturn = [];
async.waterfall([function(cb){
emails.forEach(( email, index ) => {
var msgId = email.message_id;
//fetch attachments against this attachment
var fetchAttachments = `SELECT * FROM email_attachments WHERE message_id='${msgId}'`;
connection.query(fetchAttachments, (err, attachmentsResult)=>{
email['attachments'] = attachmentsResult;                
emailsToReturn.push(email); // this show desired results here.
if(index == emails.length - 1){
cb();  
}
});
});
}],function(){
console.log(JSON.stringify(emailsToReturn, null, 4));
})

最新更新