返回for循环中AJAX链中最后一次AJAX请求的值
我有一个for
循环,在一次迭代中(某事),我需要做四个AJAX请求,然后等待最后一个请求的结果。
现在我只知道如何将数据从先前的承诺传递给另一个,就像在这个很酷的答案中一样,但我需要将最后一次AJAX调用的值返回给外部数组(并等待最后一次AJAX调用完成)以及然后继续循环中的其他功能。
attaches.forEach(function(attach)) {
if(attach.val == "val1"){
attachments.push(attach.val1);
}
if(attach.val == "val2"){
attachments.push(attach.val2);
}
if(attach.val == val3){
function func1(){
var params = [param1,param2];
return $.post(api, params.join('&'))
}
function func2(){
console.log('1111');
return new Promise(function(resolve, reject)) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
}
xhr.open('GET', img_src);
xhr.responseType = 'blob';
xhr.send();
});
}
function uploadPhoto(upload_url, bulbSend){
console.log('<Del><F7> function uploadPhoto');
return $.ajax({
url: upload_url,
type: 'POST',
data: bulbSend,
dataType: 'json',
processData: false,
contentType: false,
});
}
function saveResult(params){
return $.post(api, params.join('&'))
}
func1().then(fun1hand()).then(console.log('a32w436bya3b7naua'));
function fun1hand(){
return function(dat4a) {
return func2().then(func2hand(dat4a));
};
}
function func2hand(dat4a){
console.log('2222');
return function(datums){
console.log('3333');
var upload_url = dat4a.upload_url;
console.log('UPLOAD__URL BEFORE PROMISE '+upload_url);
var bulbSend = new FormData();
bulbSend.append('file1', datums, 'file.jpg');
return uploadPhoto(upload_url,bulbSend).then(func3hand());
}
}
function func3hand(){
return function(data2){
var params = [data2.param1, data2.param2, data2.param3];
return saveResult(params).then(pushToAttachmentsHandler());
}
}
function pushToAttachmentsHandler(){
return function(data3){
console.log('PUSUSUSUSSUSUSUUSUS PUSHHHHHHH PUSH DA BAUTTON');
console.log(attachments);
return pushDat(data3).then(console.log(attachments));
}
}
function pushDat(data3){
console.log('1111');
return new Promise(function(resolve, reject) {
attachments.push(data3.param3+"_"+data3.param1));
console.log('11111111111');
});
}
}
});
回调或承诺能够处理那种异步控制流程...
假设您的原始非工作代码是...
for(var i=0; i < 10; i++){
$.get('http://example.com/rest/users/'+i);
$.get('http://example.com/rest/posts/'+i);
$.get('http://example.com/rest/comments/'+i);
$.get('http://example.com/rest/events/'+i);
}
回调...
var i = 1;
getSet(repeater);
// define a repeater function to be used as recursive callback
function repeater (){
// increment counter
i++;
// if we still have items to process, get another set
if(i < 10){
getSet(repeater);
}
}
function getSet(cb){
// define queue
var counter = 0;
// make four api calls, defining success callbacks, which call the
// originally passed callback if the counter reaches 0. Increment counter before each request. This means the callback fires only for the last result
counter++;
$.get('http://example.com/rest/users/'+i, handleSuccess);
counter++;
$.get('http://example.com/rest/posts/'+i, handleSuccess);
counter++;
$.get('http://example.com/rest/comments/'+i, handleSuccess);
counter++;
$.get('http://example.com/rest/events/'+i, handleSuccess);
function handleSuccess(data){
// do something with data
--counter || cb();
}
}
这种模式的工作原理是这样的...
第一次调用getSet
,并带有一个repeater
函数,一旦所有的异步请求完成,预计会调用repeater
函数。 getSet
函数在进行异步调用时递增堆栈,在异步回调中递减,当堆栈getSet
为零并且队列中不再有异步作业时调用repeater
。 repeater
回调然后重复整个过程,调用getSet
并将其自身作为回调传递,直到满足条件。
它看起来很简单,可用于异步和同步ajax请求:
var myVar;
yourLoop(function() {
yourAjax(function(result) {
myVar = result;
});
});
在ajax成功(完成)回调上更改您的变量值
UPD:
如果你需要回调最后的结果,我可能会建议你这个黑客选项:
var myVar, timeout;
yourLoop(function() {
yourAjax(function(result) {
myVar = result;
clearTimeout(timeout);
timeout = setTimeout(function() {
// do something . . .
console.log('last result', myVar);
}, 1000);
});
});
注意:将1000
更改为预期的最大响应时间
上一篇: Return value from last AJAX request in AJAX chain that is inside a for loop