【发布时间】:2016-10-01 10:04:22
【问题描述】:
我看到了这个 Promise.all 的示例实现 - 它并行运行所有承诺 - Implementing Promise.all
请注意,我正在寻找的功能类似于 Bluebird 的 Promise.mapSeries http://bluebirdjs.com/docs/api/mapseries.html
我正在尝试创建 Promise.series,我有这个似乎可以按预期工作(实际上是完全错误的,不要使用它,请参阅答案):
Promise.series = function series(promises){
return new Promise(function(resolve,reject){
const ret = Promise.resolve(null);
const results = [];
promises.forEach(function(p,i){
ret.then(function(){
return p.then(function(val){
results[i] = val;
});
});
});
ret.then(function(){
resolve(results);
},
function(e){
reject(e);
});
});
}
Promise.series([
new Promise(function(resolve){
resolve('a');
}),
new Promise(function(resolve){
resolve('b');
})
]).then(function(val){
console.log(val);
}).catch(function(e){
console.error(e.stack);
});
然而,这个实现的一个潜在问题是,如果我拒绝一个承诺,它似乎没有抓住它:
Promise.series([
new Promise(function(resolve, reject){
reject('a'); // << we reject here
}),
new Promise(function(resolve){
resolve('b');
})
]).then(function(val){
console.log(val);
}).catch(function(e){
console.error(e.stack);
});
有谁知道为什么错误没有被捕获,是否有办法通过 Promises 解决这个问题?
根据评论,我做了这个更改:
Promise.series = function series(promises){
return new Promise(function(resolve,reject){
const ret = Promise.resolve(null);
const results = [];
promises.forEach(function(p,i){
ret.then(function(){
return p.then(function(val){
results[i] = val;
},
function(r){
console.log('rejected');
reject(r); // << we handle rejected promises here
});
});
});
ret.then(function(){
resolve(results);
},
function(e){
reject(e);
});
});
}
但这仍然无法按预期工作......
【问题讨论】:
-
你没有抓住内在的承诺。尝试使用
reduce()而不是forEach,通过then链接它们 -
但它不会“运行”承诺。
Promise.series获得已创建的 Promise,并在创建后立即运行。 -
不,当你通过
new Promise(executor)创建promise 时,executor函数在创建时被调用(而且是同步的)。在Promise.series中,你只能等待承诺的履行/拒绝。 -
@AlexMills 不,
then()不会“开始”承诺。Promise.all([$.get("foo.html"), $.get("bar.html")])和Promise.series([$.get("foo.html"), $.get("bar.html")])都会立即并行启动 2 个 AJAX 请求,然后等待它们的结果。如果您希望在前一个请求完成后开始下一个请求,您需要给Promise.series一个“promise factory”数组:创建(并因此“启动”)promise 的函数。 -
我会将函数数组(并将其称为任务)传递给
Promise.series并依次执行它们。传递一系列承诺对我来说没有意义 - 它的工作原理几乎与Promise.all
标签: javascript node.js ecmascript-6 es6-promise