【发布时间】:2016-04-30 03:17:27
【问题描述】:
我正在尝试构建一组 Promises 链并让它们按顺序执行。每个链在数组中的下一个条目执行之前完成。例如:[connect1, connect2, connect3],其中每个“任务”都包含一系列步骤。
我遇到的一个大问题是能够构建链并将其添加到数组中——因为它已经开始执行了。
我一直在玩的一些测试代码在这里:
function step1() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step1:", this);
resolve();
});
}
function step2() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step2:", this);
resolve();
});
}
function step3() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step3:", this);
resolve();
});
}
function promiseSeq( tasks, state ) {
let current = Promise.resolve();
for (let k = 0; k < tasks.length; ++k) {
var taskWithState = tasks[k];
if (typeof state !== 'undefined') {
taskWithState = taskWithState.bind(state);
}
current = current.then(taskWithState);
}
return current;
}
function buildChain(idx) {
// Build the connection chain (with state)
//------------------------------
var s = { conn: idx }; // some state
var q = [ step1, step2, step3 ];
return promiseSeq(q, s);
}
function streamConnect() {
// Build array of chains
//------------------------------
var q = [ ];
q.push(buildChain(1)); // e.g. connect1
q.push(buildChain(2)); // e.g. connect2
q.push(buildChain(3)); // e.g. connect3
var p = Promise.each(q, function(f) {return ( f )});
// Process promises...
p.then(function() {console.log("done")})
.catch(function(err) {console.error("catch:",err)})
return;
}
一旦我有了数组中每个“任务”的链,我想按顺序执行链。所以我的目标是让输出成为:
step1: Object {conn: 1}
step2: Object {conn: 1}
step3: Object {conn: 1}
step1: Object {conn: 2}
step2: Object {conn: 2}
step3: Object {conn: 2}
step1: Object {conn: 3}
step2: Object {conn: 3}
step3: Object {conn: 3}
我看到的是我的代码:
step1: Object {conn: 1}
step1: Object {conn: 2}
step1: Object {conn: 3}
step2: Object {conn: 1}
step2: Object {conn: 2}
step2: Object {conn: 3}
step3: Object {conn: 1}
step3: Object {conn: 2}
step3: Object {conn: 3}
谈到 Promises 时,我很不适应,我正在努力理解(没有特定的顺序):
1. 为什么 promise 的执行似乎是交错的(所有 step1 都完成了,然后是 step2,等等)?
2.我怎样才能得到我预期的输出以上的序列化执行行?
3. 可以延迟设置链吗?我看到我的线路 current = current.then(taskWithState); 最终使用 Bluebird 调用 async.invoke,但我没有找到避免这种情况的方法。
任何建议或帮助将不胜感激。
【问题讨论】:
标签: javascript promise bluebird