"while" 循环的承诺版本?
Promise version of a "while" loop?
我开始意识到,由于 ECMAScript 6 中的承诺允许对异步函数进行同步编码,因此对于每段充满承诺的代码,都有一个同步推论。例如:
var data = processData(JSON.parse(readFile(getFileName())));
等同于:
var data = getFileName()
.then(readFile)
.then(JSON.parse)
.then(processData);
现在对于我当前的用例,我想编写代码以从大量 public 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);
});
但在这一点上,我不得不链接无限的 .then
s -- 没有循环逻辑。我觉得使用递归应该可以做一些事情,但我不知道该怎么做。
我正在使用 BluebirdJS 作为我的 promise 库,所以我可以访问它们的所有辅助方法。
I feel like something should be possible using recursion
没错。您可以命名回调,以便再次引用它。只要不满足条件,return 回调的承诺。否则return最终结果:
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
});
我开始意识到,由于 ECMAScript 6 中的承诺允许对异步函数进行同步编码,因此对于每段充满承诺的代码,都有一个同步推论。例如:
var data = processData(JSON.parse(readFile(getFileName())));
等同于:
var data = getFileName()
.then(readFile)
.then(JSON.parse)
.then(processData);
现在对于我当前的用例,我想编写代码以从大量 public 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);
});
但在这一点上,我不得不链接无限的 .then
s -- 没有循环逻辑。我觉得使用递归应该可以做一些事情,但我不知道该怎么做。
我正在使用 BluebirdJS 作为我的 promise 库,所以我可以访问它们的所有辅助方法。
I feel like something should be possible using recursion
没错。您可以命名回调,以便再次引用它。只要不满足条件,return 回调的承诺。否则return最终结果:
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
});