假设我有两个异步函数,A和B,它们彼此独立。
我要做的是按顺序多次执行这些功能,如下所示
A -> B -> A -> B -> A -> ...
B等到A结束,反之亦然。
以下是我到目前为止所做的事情,我知道它不会按我想要的方式工作。
function A() {
var promise = new Promise...
...
return promise;
}
function B() {
var promise = new Promise...
...
return promise;
}
for(var i=0; i<200; i++) {
var p1 = A();
p1.then(() => {
var p2 = B();
// ----
}
}
我该如何更改代码?
答案 0 :(得分:6)
你以正确的方式前进,但你需要继续链接then
。您通常从Promise.resolve()
预先解决的承诺开始,然后使用then
添加到链中,保留每个新承诺:
let p = Promise.resolve();
for (var i=0; i<200; i++) {
p = p.then(A).then(B);
}
p.then(() => {
console.log("All done");
});
实例(20而不是200):
let counterA = 0;
let counterB = 0;
function A() {
var promise = new Promise(resolve => {
setTimeout(() => {
++counterA;
console.log("A done (" + counterA + ")");
resolve();
}, 100);
});
return promise;
}
function B() {
var promise = new Promise(resolve => {
setTimeout(() => {
++counterB;
console.log("B done (" + counterB + ")");
resolve();
}, 100);
});
return promise;
}
let p = Promise.resolve();
for (var i=0; i<20; i++) {
p = p.then(A).then(B);
}
p.then(() => {
console.log("All done");
});
&#13;
.as-console-wrapper {
max-height: 100% !important;
}
&#13;
(在实际代码中,您当然还有一个.catch
来处理拒绝;或者您将最后一个承诺返回到处理它们的其他代码。)< / p>
答案 1 :(得分:1)
您可以使用chained .then()
链接来确保在之前的调用完成后调用它们。
let cA = cB = 0;
function A() {
return new Promise(resolve => {
setTimeout(() => {
resolve("A " + ++cA);
console.log("A done");
}, 200);
});
}
function B() {
return new Promise(resolve => {
setTimeout(() => {
resolve("B " + ++cB);
console.log("B done");
}, 300);
});
}
function callConsecutive(times) {
if (times == 0) return Promise.resolve([]);
times--;
const a = A(),
b = a.then(B),
c = b.then(() => { return callConsecutive(times) });
return Promise.all([a, b, c]).then(([r1,r2,r3]) => Promise.resolve([r1,r2,...r3]));
}
callConsecutive(5).then(results => { console.log(results); })
&#13;
答案 2 :(得分:0)
您可以使用递归函数
来完成function seqAB(count) {
if(!count) Promise.resolve();
var p1 = A();
p1.then(() => {
var p2 = B();
p2.then(() => {
seqAB(count - 1);
})
})
}
seqAB(200);