【问题标题】:Nested async operations in node.jsnode.js 中的嵌套异步操作
【发布时间】:2016-05-06 00:25:56
【问题描述】:

我对为 Node.js(来自 PHP)编写代码还是很陌生,有时很难理解异步操作是否正常工作,尤其是当有多个嵌套的数据库调用/异步操作时。

例如,在这段代码中(使用 mongo),程序是否只有在任何所需帐户上设置了deleted 时才能完成? (见todo 1、2 和 3):

// array of account emails to be compared against the accounts already in the database (using `email`)
var emailsArray; 

accountsDatabase.find({}, {})
    .then(function (accountsInDB) {
        return q.all(_.map(accountsInDB, function (dbAccount) {
            // compare account's email in db with emails array in memory using .email 
            if ((emailsArray.indexOf(dbAccount.email) > -1) === false) {

                // todo 1. should there be another 'then' here or is 'return' ok in order for it to work asynchronously?

                return accountsInDB.updateById(dbAccount._id, {$set: {deleted: true}}); 
            } else {

                // todo 2. is this return needed?

                return;
            }
        }));
    })
    .then(function () {

        // TODO 3. WILL THE PROGRAM POTENTIALLY REACH HERE BEFORE `deleted` HAS BEEN SET ON THE REQUIRED ACCOUNTS?

        callback(); // all of the above has finished
    })
    .catch(function (err) {
        callback(err); // failed
    });

【问题讨论】:

  • 不要使用callback 参数,而应该return 你产生的承诺。

标签: javascript node.js mongodb asynchronous promise


【解决方案1】:

这里应该有另一个'then'还是'return'可以让它异步工作?

return accountsInDB.updateById(dbAccount._id, {$set: {deleted: true}});

如果您愿意/需要,您可以在此处链接另一个 then,但这并不重要。重要的是您 return 来自函数的承诺,以便可以等待它。如果您不这样做,该函数仍将异步工作,但会出现故障 - 它会在开始更新操作后立即继续。

需要退货吗?

else
   return;

不。它只返回undefined,就像没有return 一样。你可以省略整个else 分支。

deleted 已在所需帐户上设置之前,该程序是否可能到达此处?

callback(); // all of the above has finished

不,不会。 map 产生一个 promise 数组,q.all 发出一个等待所有它们的 promise(并用它们的结果数组实现)。 then 将在链继续之前等待从其回调返回的这个承诺。

【讨论】:

  • 很酷,谢谢,所以不用任何调整就可以离开了吗?顺便说一句,我现在添加了第二条返回语句:return accountsInDB.updateById(dbAccount._id, {$set: {deleted: false}});
  • 我会避免使用 callback 的东西,如果有的话,它应该是 .then(function(res) { callback(null, res); }, function(err) { callback(err); }) instead of .then(…).catch(…)。但除此之外还可以。它的工作,对吧?
  • 太棒了,是的,它似乎工作正常,感谢您的提示和澄清:)
猜你喜欢
  • 1970-01-01
  • 2017-04-08
  • 2012-07-15
  • 2013-08-10
  • 2023-03-16
  • 1970-01-01
  • 2016-06-17
  • 2016-08-18
  • 2017-09-17
相关资源
最近更新 更多