Return q 在所有操作完成时解决
Return q resolve when all operations complete
我有一个函数,我只想在 foreach 完成时解决。我使用 q 和 mongoose,这是大写的东西所指的,基本上我想先创建一组项目,然后运行 foreach完成后的一个函数。
function createItems() {
var deferred = Q.defer();
var itemsArray = [{ 'name' : 'spade' }, { 'name' : 'bucket' } , { 'name' : 'sand'}];
itemsArray.forEach(function(itemObj) {
var item = new Item(itemObj); // forces it to use a schema (dont worry)
Item.findOneAndUpdate({
url: item.short_name
}, item, {
upsert: true
}, function(err) {
if (!err) {
console.log(item.name + ' created.');
deferred.resolve();
} else {
deferred.reject(new Error(err));
}
});
});
return deferred.promise;
}
createItems()
.then(function() {
console.log('All items done.');
});
所以我希望在控制台上看到类似的东西;
已创建黑桃项目
已创建存储桶项目
沙项目创建
所有项目完成。
顺便说一句:您的数组存在语法问题,它包含一个对象,多次尝试写入 name
。我假设你打算有一个对象数组,每个对象都有一个 name
.
基本上,你的方法失败了,因为你在一开始就兑现了你的承诺。您需要一个代表多个异步调用完成的承诺。做到这一点的标准方法是将 承诺数组 传递到库函数中,例如 Q.all
/ Bluebird.all
/ Promise.all
。 all
函数接受一组承诺,returns 接受一组结果的承诺。它在所有承诺都解决时解决,或者在任何一个承诺拒绝时拒绝。
function createItems() {
var promisesForUpdatedDocs = [];
var itemsArray = [
{ name: 'spade'},
{ name: 'bucket'},
{ name: 'sand'}
];
itemsArray.forEach(function(itemObj) {
var item = new Item(itemObj);
var updatedDocPromise = Item.findOneAndUpdate({
url: item.short_name
}, item, {
upsert: true
}).exec(); // returns an mPromise
promisesForUpdatedDocs.push(Q(updatedDocPromise)); // using Q to turn the mPromise to a Q promise, and adding it to an array
});
return Q.all(promisesForUpdatedDocs); // creates a promise for array of results (from array of promises)
}
createItems()
.then(function(items) {
console.log('All items done:', items);
}).catch(console.log); // never forget to handle errors! Always `return` or `catch` a promise chain.
我有一个函数,我只想在 foreach 完成时解决。我使用 q 和 mongoose,这是大写的东西所指的,基本上我想先创建一组项目,然后运行 foreach完成后的一个函数。
function createItems() {
var deferred = Q.defer();
var itemsArray = [{ 'name' : 'spade' }, { 'name' : 'bucket' } , { 'name' : 'sand'}];
itemsArray.forEach(function(itemObj) {
var item = new Item(itemObj); // forces it to use a schema (dont worry)
Item.findOneAndUpdate({
url: item.short_name
}, item, {
upsert: true
}, function(err) {
if (!err) {
console.log(item.name + ' created.');
deferred.resolve();
} else {
deferred.reject(new Error(err));
}
});
});
return deferred.promise;
}
createItems()
.then(function() {
console.log('All items done.');
});
所以我希望在控制台上看到类似的东西;
已创建黑桃项目 已创建存储桶项目 沙项目创建 所有项目完成。
顺便说一句:您的数组存在语法问题,它包含一个对象,多次尝试写入 name
。我假设你打算有一个对象数组,每个对象都有一个 name
.
基本上,你的方法失败了,因为你在一开始就兑现了你的承诺。您需要一个代表多个异步调用完成的承诺。做到这一点的标准方法是将 承诺数组 传递到库函数中,例如 Q.all
/ Bluebird.all
/ Promise.all
。 all
函数接受一组承诺,returns 接受一组结果的承诺。它在所有承诺都解决时解决,或者在任何一个承诺拒绝时拒绝。
function createItems() {
var promisesForUpdatedDocs = [];
var itemsArray = [
{ name: 'spade'},
{ name: 'bucket'},
{ name: 'sand'}
];
itemsArray.forEach(function(itemObj) {
var item = new Item(itemObj);
var updatedDocPromise = Item.findOneAndUpdate({
url: item.short_name
}, item, {
upsert: true
}).exec(); // returns an mPromise
promisesForUpdatedDocs.push(Q(updatedDocPromise)); // using Q to turn the mPromise to a Q promise, and adding it to an array
});
return Q.all(promisesForUpdatedDocs); // creates a promise for array of results (from array of promises)
}
createItems()
.then(function(items) {
console.log('All items done:', items);
}).catch(console.log); // never forget to handle errors! Always `return` or `catch` a promise chain.