我正在尝试从我通过请求收到的项目列表中推送到一个数组(Mongo模型中的属性)。从这些项目中,我遍历它们以查看当前在数据库中的哪一个,如果不是这样,那么我创建一个新项目并尝试保存它。我正在使用promises来完成这项任务,但是我无法弄清楚为什么在所有承诺完成后数组都是空的。
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();
}
编辑已解决:代码吼叫,基于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
}
答案 0 :(得分:3)
这就是我没有任何第三方库的方式。
因为我只需要推迟并且我在 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 ]
。
答案 1 :(得分:0)
而不是
promises.push(deferred);
...尝试......
promises.push(deferred.promise);
此外,由于您的承诺正在解决已保存的项目,因此您可以使用q.allSettled(...)
的结果作为您的项目:
q.allSettled(promises).then(function(results) {
trans.items = results;
trans.save();
});