【问题标题】:Loop on a promise indefinitely until rejection无限期地循环一个承诺直到被拒绝
【发布时间】:2016-11-08 10:43:50
【问题描述】:

我有一个函数可以做一些异步工作并返回一个Promise,我想无限期地执行这个函数,直到promise 是rejected。

类似于以下内容:

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

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

我找到了几个可能的答案,但似乎对我的情况没有任何帮助。

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

谢谢。

【问题讨论】:

  • 您的 setTimeout 和 codepen 中的按钮 cmets 让我想知道您真正想要实现的目标是什么。承诺可能不是您所需要的。点击按钮不会导致 Promise 被拒绝。

标签: javascript loops promise es6-promise


【解决方案1】:

你可以的

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

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

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

【讨论】:

    【解决方案2】:

    对您的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 只是成为标志,因此如果您想通过单击而不是计数来停止承诺,您可以将其设为布尔值并在执行异步任务时检查它

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-17
        • 1970-01-01
        • 2018-05-09
        • 2017-03-28
        • 1970-01-01
        • 2017-02-24
        • 2017-06-19
        • 1970-01-01
        相关资源
        最近更新 更多