循环结束后,NodeJS 在循环结果中查找查询

NodeJS find query inside for loop results after the loops end

var user_id = '98-XXXXXXXX'

Contact.find({user_id: user_id})
.exec(function (err, results) {
  if (err) { 
    return next(err); 
  }
    var finalArray = [];
    for(var i = 0; i< results[0].Total; i++) {

      if(results[0].Contacts[i].name != "SPAM") {

       for(var j = 0; j < results[0].Contacts[i].phoneNumbers.length; j++){

           var number = results[0].Contacts[i].phoneNumbers[j].number
           number = number.replace(/ /g,'');
            var user_id = number.substr(number.length - 10); 

                Login.find({user_id:user_id})
                .exec(function(err,results) {
                if(err) {
                return next(err); }

                    var intCount = results.length;
                        if (intCount > 0)
                        {
                            console.log('called')
                            finalArray.push(results[0])
                            console.log(finalArray)
                        } 
               });

            }
         }

        //console.log(i,results[0].Total - 1);
        //if(i == results[0].Total - 1)



    } 
                    console.log('Ended Here',finalArray)
                    var responseTosend = {"message":finalArray,"user_id":user_id}
                    return  res.send(responseTosend);

});

EndedHere[] 这首先是空的,之后我得到 login.find 查询的结果是正确的。在所有计算之后如何获得 finalArray 的任何想法。 提前致谢

由于函数在循环中返回承诺,因此代码执行必须等到所有这些承诺都已解决。考虑使用 Promise.allPromise.map 等待。 Reference

如前所述,像这样的结构,不会return结果,而是在它们完成之前的中间函数或对象,因为 nodejs 不知道它应该先等待结果。

const x = [1,2,3]
let results = []

for (let i = 0; i < x.length; i++){
  results.push(someAsyncJobLikeADatabaseCall(x[i]))
}

// this will not return the results, but the intermediate async objects/functions
console.log(results)

这是使用 promises 和 .map 函数的更好版本。请注意,我们如何用 .map() 替换 for 循环(您可以将其视为 shorthand forEach + push() 或 for() + push()。Mongoose returns Promises if配置正确,因此您甚至不必手动定义它们,我们可以直接在 .map 中 return 它们。

const x = [1,2,3]
let results = []

async function getAsyncResults(array){
  // map returns an array, this time, an array of promises
  const promises = x.map(number => someAsyncJobLikeADatabaseCall(number))
  // Promise.all resolves, if all promises in the array have been resolved
  return Promise.all(promises)
}

try {
  let results = await getAsyncResults(x)
  // this will return the results you expect.
  console.log(results)
} catch (err) {
  console.log('Some error', err)
}