Node.js承诺:asynchronous推送到数组并保存

我目前正尝试从我通过请求接收的项目列表推送到一个数组(Mongo模型中的属性)。 从这些项目,我循环通过他们看到哪一个目前在数据库中,如果不是这样的话,那么我创build一个新的项目,并尝试保存它。 我正在使用承诺来完成这个任务,但我无法弄清楚为什么在所有的承诺完成后数组是空的。

var q = require('q'); var items_to_get = ['1', '2', '3']; // example array var trans = new Transaction({ items : [] }); var promises = []; for (var i = 0; i < items_to_get.length; i++) { var ith = i; //save current i, kinda hacky var deferred = q.defer(); //init promise //find an existing item Item.findOne({simcode: items_to_get[ith]}, function(err, item) { trans.items.push(item); // push item to transaction deferred.resolve(item); // resolve the promise }); promises.push(deferred); // add promise to array, can be rejected or fulfilled }; q.allSettled(promises).then(function(result) { console.log(trans.items); //is empty trans.save(); } 

编辑解决:代码波纹pipe,基于http://jsbin.com/bufecilame/1/edit?html,js,output ..信用去@macqm

 var items_to_get = ['1', '2', '3']; var promises = []; //I made this global items_to_get.forEach(item) { upsertItem(item); } q.allSettled(promises).then(function(result) { //loop through array of promises, add items result.forEach(function(res) { if (res.state === "fulfilled") { trans.items.push(res.value); } }); trans.save(); promises = []; //empty array, since it's global. } //moved main code inside here function upsertItem(item) { var deferred = q.defer(); //init promise //find an existing item Item.findOne({simcode: item}, function(err, item) { deferred.resolve(item); // resolve the promise // don't forget to handle error cases // use deffered.reject(item) for those }); promises.push(deferred); // add promise to array } 

代替

 promises.push(deferred); 

试试…

 promises.push(deferred.promise); 

另外,由于您的承诺正在解决保存的项目,您可以使用q.allSettled(...)的结果作为您的项目:

 q.allSettled(promises).then(function(results) { trans.items = results; trans.save(); }); 

这就是我没有任何第三方图书馆。

由于我只是需要推迟,而我在ES2017上,我认为最好不要把不必要的依赖关系复杂化。

 'use strict'; /** * @param {function(*)} callee * @param {Array} args * @returns {Promise.<*>} */ const defer = (callee, args) => { return new Promise(resolve => { resolve(callee(...args)); }); }; /** * @param {Number} one * @param {Number} two * @param {Number} timeout * @returns {Promise.<Number>} */ const asyncFunction = (one, two, timeout) => { return new Promise(resolve => { setTimeout(resolve, timeout, one + two); }); }; let promises = []; promises.push(defer(asyncFunction, [3, 7, 0])); // returns immediately promises.push(defer(asyncFunction, [10, 20, 100])); // returns after 100ms promises.push(defer(asyncFunction, [55, 45, 50])); // returns after 50ms Promise.all(promises).then(results => { console.log(results); }); 

运行上面的代码,你会得到[ 10, 30, 100 ]