使用promise收集未知大小的分页数据
Collecting paginated data of unknown size using promises
我正在查询一个REST-API以获取所有组。这些团体一批50人。在继续处理它们之前,我想收集所有这些。
到目前为止,我依赖于回调,但我希望使用promise来链接所有组的检索,然后进一步处理结果数组。
我只是不太明白如何使用promise替换递归函数调用。
我该如何使用A+promise来逃避我用这段代码创建的回调地狱
function addToGroups() {
var results = []
collectGroups(0)
function collectGroups(offset){
//async API call
sc.get('/tracks/'+ CURRENT_TRACK_ID +'/groups?limit=50&offset=' + offset , OAUTH_TOKEN, function(error, data){
if (data.length > 0){
results.push(data)
// keep requesting new groups
collectGroups(offset + 50)
}
// finished
else {
//finish promise
}
})
}
}
使用标准承诺,包装所有现有代码,如下所示:
function addToGroups() {
return new Promise(function(resolve, reject) {
... // your code, mostly as above
});
}
在代码中,完成后调用resolve(data)
,如果由于某种原因调用链失败,则调用reject()
。
为了使整个事情更像"promise",首先让函数collectGroups
返回一个promise:
function promiseGet(url) {
return new Promise(function(resolve, reject) {
sc.get(url, function(error, data) {
if (error) {
reject(error);
} else {
resolve(data);
}
});
}
}
// NB: promisify-node can do the above for you
function collectGroups(offset, stride) {
return promiseGet('/tracks/'+ CURRENT_TRACK_ID +'/groups?limit=' + stride + '&offset=' + offset , OAUTH_TOKEN);
}
然后在你的代码中使用这个Promise:
function addToGroups() {
var results = [], stride = 50;
return new Promise(function(resolve, reject) {
(function loop(offset) {
collectGroups(offset, stride).then(function(data) {
if (data.length) {
results.push(data);
loop(offset + stride);
} else {
resolve(data);
}
}).catch(reject);
)(0);
});
}
这是可行的。我正在使用https://github.com/kriskowal/q承诺。
var Q = require('q');
function addToGroups() {
var results = []
//offsets hardcoded for example
var a = [0, 51, 101];
var promises = [], results;
a.forEach(function(offset){
promises.push(collectGroups(offset));
})
Q.allSettled(promises).then(function(){
promises.forEach(function(promise, index){
if(promise.state === 'fulfilled') {
/* you can use results.concatenate if you know promise.value (data returned by the api)
is an array */
//you also could check offset.length > 0 (as per your code)
results.concatenate(promise.value);
/*
... do your thing with results ...
*/
}
else {
console.log('offset',index, 'failed', promise.reason);
}
});
});
}
function collectGroups(offset){
var def = Q.defer();
//async API call
sc.get('/tracks/'+ CURRENT_TRACK_ID +'/groups?limit=50&offset=' + offset , OAUTH_TOKEN, function(error, data){
if(!err) {
def.resolve(data);
}
else {
def.reject(err);
}
});
return def.promise;
}
如果有效,请告诉我。
以下是使用spex.sequence:的完整示例
var spex = require("spex")(Promise);
function source(index) {
return new Promise(function (resolve) {
sc.get('/tracks/' + CURRENT_TRACK_ID + '/groups?limit=50&offset=' + index * 50, OAUTH_TOKEN, function (error, data) {
resolve(data.length ? data : undefined);
});
});
}
spex.sequence(source, {track: true})
.then(function (data) {
// data = all the pages returned by the sequence;
});
我认为没有比这更简单的了;)
相关文章:
- 如何在emberjs中使用幻影假数据进行分页
- 如何在分页事件中突出显示数据表中的单词
- 数据表不显示与表的分页
- 如何使用引导程序分页器库对从PHP返回的数据进行分页
- 如何使用javascript检测数据表分页的其他页面中的复选框
- 我应该将哪些数据传递给 Spotify 应用程序才能使分页工作
- jQuery 数据表 在页面上导航时,在分页表上重置行的数据
- 如何在 PHP 中使用 OnChange 事件的下拉列表中选择一个选项后,对大量数据行设置分页
- JSF数据表分页中的当前页码
- 如何使用数据表进行客户端和服务器端的混合分页,以便对前X行进行客户端分页
- 数据表中的FixedHead没有'删除分页后无法工作
- 为什么分页数据表JQuery没有'不要使用JSF ui:重复
- RXJS 中的分页数据光标以及对 subject.onDone 和错误的混淆
- 使用承诺以递归方式检索分页数据
- 从mysql中分页数据表,自动刷新
- 使用promise收集未知大小的分页数据
- 从不在当前分页数据表上的文本框中检索值
- 模式窗口不能为分页数据表工作
- 窗口.print在ie11中没有打印表中的所有分页数据
- 屏幕抓取分页数据