2016-05-31 96 views
2

我已经认识到,由于ECMAScript 6中的承诺允许对异步函数进行同步编码,因此对于每一个有承诺的代码段,都有一个同步推论。例如:“while”循环的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; 
} 

现在的问题是,我将如何做到这一点与承诺?我可以写这样的:

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

但在这一点上,我不得不公正连锁无限.then秒 - 没有循环逻辑。我觉得应该可以使用递归,但我不知道如何去做。

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

+0

怎么样递归自调用匿名函数(最终与Promises结合)呢?这里只是一个例子:https://jsfiddle.net/f5ud8ytx/。用你自己的api调用替换超时,并使用api调用返回的promise的.then再次调用该函数,直到结束达到0(当前 - 执行直到结束高于0) – briosheje

+0

你可以用'异步each' – r3wt

回答

6

我觉得应该的东西使用递归

究竟是不可能的。您可以命名回调,以便您可以再次参考。只要条件不满足,就从回调中返回一个承诺。否则返回最终结果:

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