无法find一个简单的方法出了多个asynchronous的每个节点js(帆)
所以这是交易:
我有一个对象的数组与对象的子数组
askedAdvices askedAdvice.replayAdvices
我正在循环通过父母和foreach循环通过孩子和需要填充()两个obejcts(我使用的是帆)
孩子看起来像:
askedAdvices = { replayAdvices : [{ bookEnd : "<ID>", user : "<ID>" }] }
所以我的目标是用两个findOne查询来循环和填充bookEnd和user,但是我正在为callback地狱而生气。 这里是Models代码:
询问build议模型
module.exports = { schema : false, attributes: { bookStart : { model : 'book' }, replayAdvices : { collection: 'replybookend' }, user : { model : 'user', required : true }, text : { type : "text" } } };
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}) } }) }
我可以使用asynchronous库,但需要build议
谢谢大家!
正如评论中指出的,Waterline还没有很深的人口,但是你可以使用async.auto
摆脱回拨地狱。 诀窍是收集所有需要查找的孩子的ID,用单个查询find他们,然后将其映射回父母身上。 代码将如下所示。
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实例; 如果您使用的是更新版本的软件包, async.auto
的用法async.auto
变化(任务函数参数被切换,以便results
出现在cb
之前), _.keyBy
. _.indexBy
已被重命名为_.keyBy
。
- 访问nodejs中的JSON对象时出错
- 有没有办法将信息传递给一个async.js并行调用,所以我不必使用全局variables?
- node.js中的asynchronous编程是否加速了CPU绑定的任务?
- node.js,以同步的方式在循环中一个接一个地执行mysql查询
- 如何使Grunt等待任务完成后再运行另一个?
- 如何在JavaScript中testing基于生成器的stream量控制(ES6)?
- Nodejs没有执行asynchronous的promise函数
- 由于Nodejs的asynchronous性质而获得空数组
- node.js和一个在getInstance中具有asynchronous调用的单例