循环中的承诺问题
Issue with promises in a for loop
我遇到了一个让我有点抓狂的情况。
因此情况如下:
module.exports = {
generation: function (req, res) {
// Let's firstly fetch all the products from the productTmp Table
function fetchProductsTmp (){
ProductsTmp.find().then(function (products) {
return Promise.all(products.map (function (row){
Service.importProcess(row);
}));
});
}
fetchProductsTmp();
}
在这里,我只需调用我的模型ProductsTmp来获取数据,并通过调用importProcess来遍历我的行。
importProcess:
importProcess: function (product) {
async.series([
function (callback) {
return SousFamille.findOne({name: product.sous_famille}).then(function (sf) {
console.log('1');
if (!sf) {
return SousFamille.create({name: product.sous_famille}).then(function (_sf) {
console.log('2');
callback(null, _sf.sf_id);
});
} else {
callback(null, sf.sf_id);
}
});
},
function (callback){
console.log('3');
},
], function(err, results){
if(err) return res.send({message: "Error"});
});
}
所以我得到了我的控制台日志:1.1.1.2.3.2.3.2.3
我想要获得的是1 2 3 1 2 3 2 3,这样每个函数都要等待promise完成,然后再调用下一个。
在第一节的generation
函数中,替换
return Promise.all(products.map (function (row){
Service.importProcess(row);
}));
带有
var results = [],
pushResult = id => results.push(id);
return products.reduce(function(prev, row){//Go through all the products
//Take the previous promise, and schedule next call to Service.importProcess to be
//made after the previous promise has been resolved
return prev.then(function(){
return Service.importProcess(row).then(pushResult);
});
}, Promise.resolve())
.then(() => results);
您还需要从importProcess
返回一个承诺,这样才能工作。放弃整个async.series
的东西,做一些类似的事情
return new Promise(function(resolve, reject){
...
resolve(sf.sf_id); //instead of the callback(null, sf.sf_id)
...
});
更新:这会强制对Service.importProcess的调用是连续的,而不是并发的,这确实会影响对generation
的调用的总体性能。但我想你有比顺序console.log更充分的理由这样做。
对不起,忍不住想在ES6中做这件事,基本上可以减少到单行,就像Bergi所说的,异步是多余的(使用Bluebird Promise Library):
importProcess: product =>
SousFamille.findOne({name: product.sous_famille})
.then(sf => sf? sf.sf_id : SousFamille.create({name: product.sous_famille}).then(_sf => _sf.sf_id))
// the other module
module.exports = {
generation: (req, res) => ProductsTmp.find()
.then(products => Promise.mapSeries(products, Service.importProcess.bind(Service)) )
.then(ids => res.send({ids}))
.catch(error => res.send({message: 'Error'}))
}
也正如noppa所说,你的问题是Service.importProcess(row)
中缺少return
,ES5:中的代码相同
module.exports = {
generation: function (req, res) {
ProductsTmp.find()
.then(function (products) {
return Promise.mapSeries(products, Service.importProcess.bind(Service)) );
}).then(function(ids){
res.send({ids: ids});
}).catch(function(error){
res.send({message: 'Error'});
})
}
importProcess: function (product) {
return SousFamille.findOne({name: product.sous_famille})
.then(function (sf) {
if (sf) return sf.sf_id;
return SousFamille.create({name: product.sous_famille})
.then(function (_sf){ return _sf.sf_id});
});
}
相关文章:
- 简单的ES6承诺问题-交换解决和拒绝参数
- 一个承诺换多个承诺-并发问题
- Node JS异步承诺.所有问题
- 在我的案例中,如何解决我的承诺问题
- 递归承诺调用 - 内存范围变量问题
- 循环中的承诺问题
- jQuery在一系列承诺上出现问题
- 在承诺函数从 pouchdb 填充数据之前触发 Ionic/Angular $watch的问题
- 有问题与承诺角度.控制台日志不适用于 HTTP 请求
- 了解使用AngularJS承诺,他们将如何帮助解决这个问题
- jquery承诺和骨干的问题
- 在 angularjs 控制器中对承诺调用进行单元测试时遇到问题
- Keystone.js嵌套承诺 -> foreach -> 列表查找范围问题
- JQuery承诺面临的问题
- 承诺,然后绑定问题
- 命令失败: gm 识别: 无法打开文件 (2) [没有这样的文件或目录].通用模块和 ES6 承诺的问题
- JS承诺/异步澄清问题
- 解析云代码-承诺问题
- 使用reduce串行链接Javascript承诺时的作用域问题
- 这个承诺函数的代码出了什么问题