Node.js Can';t为每个节点js(sails)找到一种摆脱多个异步的简单方法

Node.js Can';t为每个节点js(sails)找到一种摆脱多个异步的简单方法,node.js,asynchronous,sails.js,Node.js,Asynchronous,Sails.js,这就是交易: 我有一个对象数组和一个子对象数组 askedAdvices askedAdvice.replayAdvices 我通过父循环,foreach通过子循环,需要填充()两个OBEJCT(我使用SAIL) 这孩子看起来像: askedAdvices = { replayAdvices : [{ bookEnd : "<ID>", user : "<ID>" }] } ReplyBookEnd模型 mod

这就是交易:

我有一个对象数组和一个子对象数组

askedAdvices 
   askedAdvice.replayAdvices
我通过父循环,foreach通过子循环,需要填充()两个OBEJCT(我使用SAIL)

这孩子看起来像:

askedAdvices = {
     replayAdvices : [{
       bookEnd : "<ID>",
       user : "<ID>"
    }]
  }
ReplyBookEnd模型

module.exports = {
  schema : false,
  attributes: {
    bookEnd : {
        model : 'book'
    },
    user : {
        model : 'user',
        required : true
    },
    text : {
      type : "text"
    }
  }
};
以下是方法代码:

getAskedAdvices : function(req, res) { 

    var queryAskedAdvices = AskedAdvices.find()
        .populate("replayAdvices")
        .populate("user")
        .populate("bookStart")

    queryAskedAdvices.exec(function callBack(err,askedAdvices){

        if (!err) {
            askedAdvices.forEach(function(askedAdvice, i){

                askedAdvice.replayAdvices.forEach(function(reply, i){

                     async.parallel([
                        function(callback) {
                            var queryBook = Book.findOne(reply.bookEnd);
                            queryBook.exec(function callBack(err,bookEndFound) {
                                if (!err) {
                                    reply.bookEnd = bookEndFound;
                                    callback();
                                }                                   
                            })  
                        },
                        function(callback) {
                            var queryUser = User.findOne(reply.user)
                            queryUser.exec(function callBack(err,userFound){
                                if (!err) {
                                    reply.user = userFound; 
                                    callback();
                                }

                            })
                        }
                     ], function(err){
                        if (err) return next(err);

                        return res.json(200, reply);
                     })


                })  
            })



        } else {
            return res.json(401, {err:err})
        }
    })
}
我可以使用异步库,但需要建议


谢谢大家

正如评论中指出的,Waterline还没有深入的填充,但是您可以使用
async.auto
来摆脱回调地狱。诀窍是收集您需要查找的所有子项的ID,通过单个查询找到它们,然后将它们映射回父项。代码如下所示

async.auto({

  // Get the askedAdvices 
  getAskedAdvices: function(cb) {
    queryAskedAdvices.exec(cb);
  },

  // Get the IDs of all child records we need to query.
  // Note the dependence on the `getAskedAdvices` task
  getChildIds: ['getAskedAdvices', function(cb, results) {
    // Set up an object to hold all the child IDs
    var childIds = {bookEndIds: [], userIds: []};
    // Loop through the retrieved askedAdvice objects
    _.each(results.getAskedAdvices, function(askedAdvice) {
      // Loop through the associated replayAdvice objects
      _.each(askedAdvice.replayAdvices, function(replayAdvice) {
        childIds.bookEndIds.push(replayAdvice.bookEnd);
        childIds.userIds.push(replayAdvice.user);
      });
    });
    // Get rid of duplicate IDs
    childIds.bookEndIds = _.uniq(childIds.bookEndIds);
    childIds.userIds = _.uniq(childIds.userIds);
    // Return the list of IDs
    return cb(null, childIds);
  }],

  // Get the associated book records.  Note that this task
  // relies on `getChildIds`, but will run in parallel with
  // the `getUsers` task
  getBookEnds: ['getChildIds', function(cb, results) {
    Book.find({id: results.getChildIds.bookEndIds}).exec(cb);
  }],

  getUsers: ['getChildIds', function(cb, results) {
    User.find({id: results.getChildIds.userIds}).exec(cb);
  }]

}, function allTasksDone(err, results) {

  if (err) {return res.serverError(err);

  // Index the books and users by ID for easier lookups
  var books = _.indexBy(results.getBookEnds, 'id');
  var users = _.indexBy(results.getUsers, 'id');

  // Add the book and user objects back into the `replayAdvices` objects
  _.each(results.getAskedAdvices, function(askedAdvice) {
    _.each(askedAdvice.replayAdvices, function(replayAdvice) {
      replayAdvice.bookEnd = books[replayAdvice.bookEnd];
      replayAdvice.user = users[replayAdvice.bookEnd];
    });
  });

});

注意,这是假设Sails的内置Lodash和异步实例;如果您使用的是这些软件包的较新版本,
async.auto
的用法稍有改变(任务函数参数被切换,使得
结果
出现在
cb
之前),并且
.indexBy
已重命名为
.keyBy

是否可以显示一些代码??@vkstack yes,回到这里,阿萨皮,你这么做是因为船帆上没有深帆吗?@Bonanza是的,这就是问题所在deal@Asso-试试这个解决方案。将此代码添加到Sails需要几分钟的时间,并且可以将此代码减少到几行。非常感谢!终于了解了async.auto的工作原理,greta解释!
async.auto({

  // Get the askedAdvices 
  getAskedAdvices: function(cb) {
    queryAskedAdvices.exec(cb);
  },

  // Get the IDs of all child records we need to query.
  // Note the dependence on the `getAskedAdvices` task
  getChildIds: ['getAskedAdvices', function(cb, results) {
    // Set up an object to hold all the child IDs
    var childIds = {bookEndIds: [], userIds: []};
    // Loop through the retrieved askedAdvice objects
    _.each(results.getAskedAdvices, function(askedAdvice) {
      // Loop through the associated replayAdvice objects
      _.each(askedAdvice.replayAdvices, function(replayAdvice) {
        childIds.bookEndIds.push(replayAdvice.bookEnd);
        childIds.userIds.push(replayAdvice.user);
      });
    });
    // Get rid of duplicate IDs
    childIds.bookEndIds = _.uniq(childIds.bookEndIds);
    childIds.userIds = _.uniq(childIds.userIds);
    // Return the list of IDs
    return cb(null, childIds);
  }],

  // Get the associated book records.  Note that this task
  // relies on `getChildIds`, but will run in parallel with
  // the `getUsers` task
  getBookEnds: ['getChildIds', function(cb, results) {
    Book.find({id: results.getChildIds.bookEndIds}).exec(cb);
  }],

  getUsers: ['getChildIds', function(cb, results) {
    User.find({id: results.getChildIds.userIds}).exec(cb);
  }]

}, function allTasksDone(err, results) {

  if (err) {return res.serverError(err);

  // Index the books and users by ID for easier lookups
  var books = _.indexBy(results.getBookEnds, 'id');
  var users = _.indexBy(results.getUsers, 'id');

  // Add the book and user objects back into the `replayAdvices` objects
  _.each(results.getAskedAdvices, function(askedAdvice) {
    _.each(askedAdvice.replayAdvices, function(replayAdvice) {
      replayAdvice.bookEnd = books[replayAdvice.bookEnd];
      replayAdvice.user = users[replayAdvice.bookEnd];
    });
  });

});