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

Loop on a promise indefinitely until rejection

我有一个执行一些异步工作的函数和 returns 一个 Promise,我想无限期地执行这个函数,直到 rejected。

类似于以下内容:

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();
     });
})();

修改了您的 codepen

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 只是成为标志,所以如果你想通过点击而不是计数来停止承诺,你可以将它设为 bool 并在执行异步任务时检查

取决于你希望逻辑和拒绝发生的位置,但假设你希望承诺本身是自我执行的(否则异步执行本身可能会循环)它可以 return 本身作为一个新的承诺:

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();