node.js - Q.all 在 forEach 之前运行

标签 node.js asynchronous q

我正在尝试创建一个 Promise 函数来读取电子邮件数组,然后找到用户 ID 并将其推送到另一个数组。

问题是我的 Q.all 函数在 _.forEach 完成之前运行。检查一下:

var deferred = Q.defer(),
    promises = [],
    _ = require('lodash');

_.forEach(users, function(user) {
    User.findOne({
      username: user
    }, function(err, member) {
      if (err)
        console.log(err);

      var memberId = member._id;
      promises.push(members.push(memberId));
    });
});

Q.all(promises)
  .then(function(promises) {
    deferred.resolve(promises);
    console.log(promises); // This always returns -> []
  })
  .catch(function(err) {
    deferred.reject(err);
  });

return deferred.promise;

因此,每次我尝试 console.log 我的 Promise 数组时,都会得到一个空数组。我什至尝试使用 JavaScript 原生 forEach 函数,但它不起作用。

forEach 存在问题,还是 Q.all 不是适合这种情况的函数?

提前致谢。

<小时/>

已解决(罗伯特·莫斯卡尔建议的解决方案)

就我而言,async 库和 Q.defer() 解决了这个问题。

var async = require('async'),
    deferred = Q.defer();

async.map(users, function(each, done){
  User.findOne({
    username: each
  }, function(err, member) {
      if (err)
        console.log(err);
        done(null, member._id);
      });
  }, function(err, results){
    if (err)
      deferred.reject(err);
    deferred.resolve(results);
});

return deferred.promise;

最佳答案

您的问题是 User.findOne 函数是异步的,因此 Q.all 函数会在将任何内容推送到 Promise 数组之前执行。

通常最好不要混合回调和 promise 。至于修复它。如果这是一个 Mongoose 模型,那么您可以使用基于 Promise 的 findOne 版本:

var deferred = Q.defer(),
    promises = [],
    _ = require('lodash');

_.forEach(users, function(user) {
    promises.push(User.findOne({
      username: user}));
});

Q.all(promises)
  .then(function(promises) {
    deferred.resolve(promises);
    console.log(promises); // This always returns -> []
  })
  .catch(function(err) {
    deferred.reject(err);
  });

return deferred.promise;

或者您可以使用异步库,它可能看起来像这样:

async.map(users, function(each, done){

 User.findOne({
      username: user
    }, function(err, member) {
      if (err)
        console.log(err);
        done(null, member._id); 

    });
},
function(err, results){
  //results holds your array of ids
    }
);

关于node.js - Q.all 在 forEach 之前运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37278718/

相关文章:

Node.js 脚本未从 crontab 执行

c# - 操作系统必须支持异步方法或者是异步程序级功能

javascript - AngularJS 处理 $q.all 中被拒绝的资源

android - 每个 ListView 项目中的旋转进度条

android - 异步任务进度对话框显示太晚

javascript - 动态数组 promise 序列

javascript - Angular 从不同的 Promise 构造 ViewModel

javascript - React.js 服务器端渲染和事件处理程序

node.js - 如何在 JEST 测试用例中检查全局获取的响应

javascript - 如何使用 JSZip 使用 Node.js 中的缓冲区内容生成 zip 文件?