【问题标题】:Promise version of a "while" loop?“while”循环的承诺版本?
【发布时间】:2016-09-29 20:45:49
【问题描述】:

我已经意识到,由于 ECMAScript 6 中的 Promise 允许对异步函数进行同步编码,因此对于每个载有 Promise 的代码段都有一个同步推论。例如:

var data = processData(JSON.parse(readFile(getFileName())));

等同于:

var data = getFileName()
    .then(readFile)
    .then(JSON.parse)
    .then(processData);

现在,对于我当前的用例,我想编写代码以从大量公共 API 中提取数据。 API 是分页的,所以在纯粹的同步世界中,我会编写如下内容:

var data = [];
var offset = 0;
var total = 10000; // For example - not actually how this would work
while( offset < total ) {
    data.concat(getDataFromAPI(offset));
    offset = data.length;
}

现在我的问题是,我将如何使用 Promise 做到这一点?我可以这样写:

var data = [];
var offset = 0;
var total = 10000;
getDataFromAPI(offset)
    .then(function(newData){
        data.concat(newData);
        return getDataFromAPI(data.length);
    });

但在这一点上,我不得不链接无限 .thens —— 没有循环逻辑。我觉得使用递归应该可以实现,但我不知道该怎么做。

我使用BluebirdJS 作为我的承诺库,所以我可以访问他们所有的辅助方法。

【问题讨论】:

  • 用递归自调用匿名函数(最终与 Promises 结合)怎么样?这里只是一个例子:jsfiddle.net/f5ud8ytx。将超时替换为您自己的 api 调用,并使用 api 调用返回的 promise 的 .then 再次调用该函数,直到 end 达到 0(当前--执行直到 end 高于 0)
  • 你可以通过async-each轻松做到这一点

标签: javascript node.js promise bluebird


【解决方案1】:

我觉得使用递归应该有可能实现

没错。您可以命名回调,以便再次引用它。只要条件不满足,就从回调中返回一个承诺。否则返回最终结果:

getDataFromAPI(offset)
  .then(function next(newData){
    data.concat(newData);
    var newOffset = data.length;
    return newOffset < total ? getDataFromAPI(newOffset).then(next) : data;
  })
  .then(function(data) {
    console.log(data); // final result
  });

【讨论】:

    猜你喜欢
    • 2013-06-17
    • 2017-04-21
    • 2015-11-13
    • 2015-06-05
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    相关资源
    最近更新 更多