javascript - 链接异步函数 Node.js bluebird mongoskin

标签 javascript node.js asynchronous promise bluebird

我已经阅读了很多关于如何链接异步函数的文章,但我似乎无法正确理解!

如标题所示。我正在尝试将 mongoskin 数据库调用链接在一起,以便我可以分块收集所有信息,然后最终在响应中发送累积结果。

我的对象用户是:

var User = {
       username: 'someusername',
       accounts: [{name: 'account_1'}, {name: 'account_2'}]
   }

我需要为每个帐户收集数据,然后在响应中发送累积的数据。所以我使用以下 for 循环来遍历帐户:

var promise = require('bluebird');
var db = require('mongoskin').db('mongodb://localhost/someDB');

for(var x in user.accounts){
   //Fetch account data
   user.accounts[x].accountData = fetchAccountData(user.accounts[x].name);
}

//Finally send the collected response
response.send(user);

函数 fetchAccountData 如下所示:

function fetchAccountData(screen_id){
   db.collection('master')
     .aggregate([
        {$match: {screen_id: screen_id}}
      ], function(err, res){
           if(err)
              return null;
           else{
              console.log('Done', screen_id);
              return res;
          }
     });
 }

我怎样才能将它链接起来以具有以下算法:

 start:
      for each account:
           fetchDataForAccount
      Finally:
           Send Response 

最佳答案

您的算法可以使用以下代码实现:

var Promise = require('bluebird');
var mongo = require('mongoskin'), db;

Promise.promisifyAll(mongo.Collection.prototype);

db = mongo.db('mongodb://localhost/someDB');

Promise.all(user.accounts.map(function(acct) {
  return fetchAccountData(acct.name).then(function(data) {
    acct.accountData = data;
  });
}))
.then(function() {
  response.send(user);
})
.catch(function(err) {
  // handle error
});

function fetchAccountData(screen_id){
   return db
     .collection('master')
     .aggregateAsync([
        {$match: {screen_id: screen_id}}
      ]);
}

编辑:这是代码的分解

您需要做的第一件事是确保 aggregate 返回一个 Promise 而不是使用延续(例如回调)。您可以使用 bluebird 的神奇 promisification 来做到这一点abilities :) 这里我们在 mongo.Collection.prototype 上使用它,以便在调用 collection() 时它会返回一个支持 promise 的集合实例。然后我们有 fetchAccountData return aggregateAsync 返回的 promise ,这样客户端就有办法知道该 promise 何时得到解决。

接下来,我们映射帐户中的每个帐户并返回一个 promise ,一旦帐户数据被获取并且它已被分配给帐户对象,该 promise 就会履行。然后我们使用 Promise.all这将返回一个 promise ,“当数组中的所有项目都得到满足时”(来自文档)。

最后,我们必须使用 then() 来“等待”,直到从 all 返回的 promise 已经解决,最后发送回带有完整用户对象的响应。

关于javascript - 链接异步函数 Node.js bluebird mongoskin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30821668/

相关文章:

javascript - 如何从异步调用返回响应?

javascript - 我需要一个定制的移动数字键盘

javascript - MongoDB (php) - 将文档属性作为数组而不是多个属性返回

javascript - 如何仅在需要时运行 Google Cloud SQL?

javascript - react : Cannot access index of an array in a state (index undefined)

javascript - Express 服务器上的同步编程是否会阻止其他访问者加载页面?

javascript - 是什么原因导致此 Vue 3 应用程序中 prop 错误的类型检查失败?

javascript - 获取选中复选框的名称

node.js - gcloud 应用程序部署构建失败,并出现错误:找不到模块 'link-module-alias'

c# - Task.Delay.ContinueWith 和使用 Task.Delay 进行异步等待之间有什么区别(如果有)?