用蓝鸟链接递归承诺

时间:2015-06-19 12:55:52

标签: javascript recursion promise bluebird

我有一个带有递归承诺doAsyncRecursive()的promise链,如下所示:

setup: function(editor) {
  editor.addButton('datepicker', {
    type: 'button',
    class: 'MyCoolBtn',
    text: 'Datepicker',
    tooltip: 'Pick a date',
    onClick: function() {
      $('#datepicker').datepicker('show')
    },
    icon: true,
  });
}

doAsync().then(function() { return doAsyncRecursive(); }).then(function() { return doSomethingElseAsync(); }).then(function(result) { console.log(result); }).catch(errorHandler); 必须做一些事情,如果它最初没有成功,那么我想在每5秒尝试一次,直到它完成。这是我的诺言功能:

doAsyncRecursive()

但是当我执行时,function doAsyncRecursive() { return new Promise(function(resolve, reject) { //do async thing if (success) { resolve(); } else { return new Promise(function(resolve, reject) { setTimeout(function() { doAsyncRecursive(); }, 5000); }); } }); } 在第二次尝试成功并且doAsyncRecursive()被调用后,链不会继续(如果尝试在第一次尝试时成功,则会继续)。

我需要采用什么模式才能完成这项工作?

1 个答案:

答案 0 :(得分:7)

抓住失败,等待五秒钟,然后再试一次。

function doAsyncRecursive() {
    return doAsyncThing().catch(function() {
        return Promise.delay(5000).then(doAsyncRecursive);
    });
}

这里doAsyncThing是一个与OP代码中的//do async thing注释相对应的函数,定义为返回一个promise。在原始代码中,使用success标志测试“do async thing”的成功或失败,但根据定义,异步例程不会传递这样的标志;他们通过回调或承诺提供结果。上面的代码假定doAsyncThing返回一个promise。它还假设“失败”,在“不返回我想要的反应”的意义上,由拒绝的承诺表示。如果将“成功”或“失败”定义为履行承诺的某个特定价值,那么您想要做

function doAsyncRecursive() {
    return doAsyncThing().then(function(success) {
        if (success) return success;
        else return Promise.delay(5000).then(doAsyncRecursive);
    });
}