jQuery递归AJAX调用承诺
jQuery Recursive AJAX Call Promise
我仍在尝试如何在递归AJAX调用中使用jQuery延迟对象。我有一个类似的代码
function request(page, items){
//building the AJAX return value for JSFiddle dummy AJAX endpoint
var ret = {
totalPage: 10,
currentPage: page,
items: []
};
for (var i = page; i < (page + 5); i++){
ret.items.push(i);
}
//calling the AJAX
$.ajax({
url: '/echo/json/',
method: 'POST',
dataType: 'json',
data: {
delay: 1,
json: JSON.stringify(ret)
},
success: function(data){
if (data.currentPage <= data.totalPage){
var filtered = data.items.filter(function(el){
return el % 2 == 1;
});
var newitems = items.concat(filtered);
console.dir(newitems);
request(data.currentPage + 1, newitems);
} else {
console.dir(items);
//resolve all item
}
}
});
}
function requestAll(){
request(1, []);
//should return a promise tha contains all items
}
这是JSFiddlehttp://jsfiddle.net/petrabarus/BHswy/
我知道如何在单个AJAX调用中使用promise,但我不知道如何在递归AJAX调用中将其使用。我想用类似下面的方式调用requestAll
函数
var promise = requestAll();
promise.done(function(items){
console.dir(items);
});
我该怎么做?
如果要使用promise,则不应使用success
参数。相反,您希望return
是一个承诺,并且希望使用then
将一个承诺的结果转换为不同的结果,甚至可能是另一个承诺。
function request(page) {
…
// return the AJAX promise
return $.ajax({
url: '/echo/json/',
method: 'POST',
dataType: 'json',
data: {
delay: 1,
json: JSON.stringify(ret)
}
});
}
function requestOddsFrom(page, items) {
return request(page).then(function(data){
if (data.currentPage > data.totalPage) {
return items;
} else {
var filtered = data.items.filter(function(el){ return el%2 == 1; });
return requestOddsFrom(data.currentPage + 1, items.concat(filtered));
}
});
}
function requestAll(){
return requestOddsFrom(1, []);
}
requestAll().then(function(items) {
console.dir(items);
});
由于您已经在一个接一个地对Ajax操作进行排序,而无需完全重新构造代码,因此您可以只使用上次Ajax调用中解决的一个延迟操作:
function request(page, items, defer){
//building the AJAX return value for JSFiddle dummy AJAX endpoint
var ret = {
totalPage: 10,
currentPage: page,
items: []
};
for (var i = page; i < (page + 5); i++){
ret.items.push(i);
}
//calling the AJAX
$.ajax({
url: '/echo/json/',
method: 'POST',
dataType: 'json',
data: {
delay: 1,
json: JSON.stringify(ret)
},
success: function(data){
if (data.currentPage <= data.totalPage){
var filtered = data.items.filter(function(el){
return el % 2 == 1;
});
var newitems = items.concat(filtered);
console.dir(newitems);
request(data.currentPage + 1, newitems, defer);
} else {
console.dir(items);
//resolve the deferred
defer.resolve(items);
}
}
});
}
function requestAll(){
var deferred = jQuery.Deferred();
request(1, [], deferred);
return deferred.promise();
}
requestAll().done(function(items) {
// all ajax calls are done
});
好吧,经过大量新的promise学习,这里有一个使用promise链接(从.then()
处理程序返回promise)的完全promise版本。从Benji的实现中借鉴和学习了一些概念,但它的组织方式有点不同,并对学习进行了评论(实际上,如果没有评论和伪Ajax调用,它会很短):
function requestPages(startPage, endPage) {
function request(page, items){
// building the AJAX return value for
// JSFiddle dummy AJAX endpoint
var ret = {
currentPage: page,
items: []
};
for (var i = page; i < (page + 5); i++){
ret.items.push(i);
}
// Do Ajax call, return its promise
return $.ajax({
url: '/echo/json/',
method: 'POST',
dataType: 'json',
data: {
delay: 1,
json: JSON.stringify(ret)
}
}).then(function(data) {
// mock filter here to give us just odd values
var filtered = data.items.filter(function(el){
return el % 2 == 1;
});
// add these items to the ones we have so far
items = items.concat(filtered);
// if we have more pages to go, then do the next one
if (page < endPage){
// Advance the currentPage, call function to process it and
// return a new promise that will be chained back to the
// promise that was originally returned by requestPages()
return request(page + 1, items);
} else {
// Finish our iteration and
// return the accumulated items.
// This will propagate back through
// all the other promises to the original promise
// that requestPages() returned
return(items);
}
});
}
// call the first request and return it's promise
return request(startPage, []);
}
// request pages 1 through 10 inclusive
requestPages(1, 10).done(function(items) {
// all ajax calls are done
console.log(items);
});
工作jsFiddle:http://jsfiddle.net/jfriend00/pr5z9/(请耐心等待,执行10个Ajax调用需要10秒钟,每个调用需要1秒钟)。
我注意到这个版本的一个问题是,因为它只使用$.ajax()
创建的promise,所以代码无法使用.notify()
来触发进度通知。我发现我想在每次Ajax调用完成时,在最初返回的promise上触发一个进度通知,但如果没有创建自己的Deferred,我就无法做到这一点,因为你不能在promise上执行.notify()
,只能在Deferred上执行。我不知道如何解决这个问题,并坚持Benji的架构,即不创建/解决您自己的延迟。
- 等待循环调用的所有承诺完成
- AngularJS因果报应测试规范承诺未解析,且未调用.then()
- 谷歌日历 api 调用可以在角度工厂内返回承诺吗?
- JavaScript - 返回承诺和/或调用回调
- 如何在使用替代承诺时解释 ajax 调用中的错误
- 递归承诺调用 - 内存范围变量问题
- “未捕获(在承诺中)”在获取“then”方法中调用拒绝函数时
- 使用 Promise 在另一个函数中调用带有 Bluebird 承诺库的函数
- javascript承诺在循环中或如何逐个调用函数
- 按照承诺,通过与chai的函数调用验证已解析承诺的内容
- 基于DOM插入承诺对API调用进行限制
- 在 Mocha 中,返回将被拒绝的承诺与调用 done(err) 的效果不同
- 进行多个 http 调用并使用承诺合并结果
- 如何在第一次调用后重新调用承诺
- Javascript 承诺 .catch 仍然调用 final variable.then
- 在猫鼬中创建承诺时,不会调用执行器
- 在 angularjs 控制器中对承诺调用进行单元测试时遇到问题
- jquery 使用承诺调用两次动画完成
- 在 javascript 中进行嵌套承诺调用
- 承诺调用他们的成功回调太晚了