无限期地循环承诺,直到被拒绝

Loop on a promise indefinitely until rejection

本文关键字:拒绝 循环 承诺 无限期      更新时间:2023-09-26

我有一个函数可以执行一些异步工作并返回Promise,我想无限期地执行此函数,直到承诺被reject

如下所示:

doSomethingAsync().
    .then(doSomethingAsync)
    .then(doSomethingAsync)
    .then(doSomethingAsync)
    // ... until rejection

我做了一个小CodePen,所以我可以测试潜在的解决方案:http://codepen.io/JesmoDrazik/pen/pbAovZ?editors=0011

找到了几个可能的答案,但似乎没有什么适合我的情况。

如果有人有解决方案,我会很高兴,因为我找不到任何东西!

谢谢。

你可以做

(function loop(){
     doSomethingAsync().then(loop);
})();

但是看着你的笔,不清楚拒绝应该来自哪里。如果要在用户单击按钮时停止重复操作,可以在按钮处理中更改状态,然后执行

(function loop(){
     doSomethingAsync().then(function(){
          if (!stopped) loop();
     });
})();

对代码笔进行了修改

var FAKE_COUNT = 0;
function doSomething() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('doing something async: ' + FAKE_COUNT)
      if (FAKE_COUNT < 10) {
        resolve();
      } else {
        reject();
      }
      FAKE_COUNT ++;
    }, 1000);
  });
}
const button = document.querySelector('.js-button');
button.addEventListener('click', () => {
  // maybe we can do something here ?
})
function test() {
  doSomething().then(test).catch(() => {
    console.log("Rejected")
  });
}
test();

FAKE_COUNT只是成为标志,所以如果你想通过点击而不是计数来停止承诺,你可以把它做成一个布尔值,并在执行异步任务时检查

根据您希望逻辑和拒绝发生的位置,但假设您希望承诺本身是自执行的(否则异步执行本身可能会循环),它可以将自身作为新承诺返回:

function doSomething() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log('doing something async');
        resolve();
    }, 1000);
  }).then(()=>doSomething());
}

对于拒绝部分,最简单的方法是引入一个标志,(尽管这将使承诺不那么自包含):

var stop = false;
function doSomething() {
  return new Promise((resolve, reject) => {
    if(stop)
        reject();
    else{
      setTimeout(() => {
        console.log('doing something async');
        resolve(); //(check for stop could be done here as well)
      }, 1000);
    }
  }).then(()=>doSomething());
}
const button = document.querySelector('.js-button');
button.addEventListener('click', () => {
  stop = true;
});
doSomething();