如何连续多次执行多个异步函数?

时间:2017-11-01 10:38:01

标签: javascript asynchronous

假设我有两个异步函数,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();
   // ----
  }
}

我该如何更改代码?

3 个答案:

答案 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):

&#13;
&#13;
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;
&#13;
&#13;

(在实际代码中,您当然还有一个.catch来处理拒绝;或者您将最后一个承诺返回到处理它们的其他代码。)< / p>

答案 1 :(得分:1)

您可以使用chained .then()链接来确保在之前的调用完成后调用它们。

&#13;
&#13;
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;
&#13;
&#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);