如何在节点js

时间:2018-08-29 14:20:19

标签: 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。但这也不起作用。任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:1)

基本上,这里发生的是emailsToReturn是全局变量,可以在任何地方访问。您正在更新emailsToReturn的值,然后尝试打印它。


但是真正发生的事情是JavaScript在后台更新了emailsToReturn的值,而在该过程进行的同时,JavaScript执行下一条指令console.log。因此值仍在后台更新,您可以转到下一条指令并打印仍相同的变量值。

如何解决?
您可以使用异步/等待(https://www.geeksforgeeks.org/using-async-await-in-node-js/
我已经使用过await。现在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)

答案 1 :(得分:1)

基本上,由于nodejs的异步特性,您要尝试执行的操作不会获得期望的结果。您的控制台在循环之前运行(由于数据库操作而异步)。在初始化“电子邮件”之后,您可以使用异步库中的Waterfall方法并尝试类似的方法:

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));
})