Javascript: 如何创建无限循环的承诺?

Javascript: how to create an infinite-loop of promises?

我想在Javascript中编写以下伪代码:

function asyncOperation() {
   return new Promise((resolve, reject) => {
      ....
   }
}

while (true) { 
    result = asyncOperation()
    if result is good then break the loop;
    else loop again
}

我用文字解释一下:asyncOperation 使用 Promise,例如 AJAX 调用。我希望如果承诺被拒绝,那么将再次调用 asyncOperation。你知道如何在 Javascript 中完成吗?

如果你要使用一个循环,那么你将不得不使用 await 因为否则,你的循环将永远 运行 而永远不会给异步操作任何循环来实际处理它的完成:

while (true) { 
    result = await asyncOperation()
    if (good result) {
         break;
    }
}

当然,这需要在声明为 async.

的函数中

await 之前,通常的方法是使用局部函数和 recursive-looking 结构(顺便说一句,递归没有任何堆栈 build-up 因为异步操作):

function run() {
    return asyncOperation().then(result => {
        if (good result) {
            return result;
        } else {
            // try again
            return run();
        }
    });
}

run().then(result => {
   console.log(result);
}).catch(err => {
   console.log(err);
});

而且,通常您会在再次调用 asyncOperation() 之前插入一些小的延迟,以避免攻击目标服务器。并且,您将有超时或最大重试次数,以避免此循环永远 运行s 的情况。

我创建了一个循环函数来做到这一点

let count = 0;
function asyncOperation() {
  return new Promise((resolve, reject) => {
    if (count < 10) {
      console.log('reject', count++);
      reject();
      return;
    }
    resolve(console.log('resolve', count));
  });
}

async function loop() {
  while (true) {
    try {
      await asyncOperation();

      break;
    } catch {
      continue;
    }
  }
}

loop();

结果是这样的:

reject 0
reject 1
reject 2
reject 3
reject 4
reject 5
reject 6
reject 7
reject 8
reject 9
resolve 10

这样的东西还不够吗:

async function loopUntilTrue() {
  let success = false;

  while (!success) {
    try {
      await asyncOperation();
      success = true;
    } catch {
      success = false;
    }
  }
}