我有一个编码问题,我想循环通过并调用ajax调用,但我不希望发送另一个请求,直到第一个请求完成.我已经尝试将其设置为asyc = false并添加onsuccess回调.但似乎循环继续运行,这给了我无序响应和并行请求.
function duplicateOmsid(totalAmount, omsid) {
var url = '/portal/GetBulkcopyAmountServlet';
var errorString;
new Ajax.Request(
url, {
method: 'post',
parameters: {
totalAmount: totalAmount,
omsid: omsid
},
async: false,
onSuccess: function(transport) {
dataResponse = transport.responseText.evalJSON();
createWorkflow(totalAmount, omsid, dataResponse);
},
…..
function createWorkflow(totalAmount, omsid, bulkAmount) {
var amountProccessed = 0;
for( i = 0; amountProccessed < totalAmount; i++ ) { // Loop through source
var duplicateAmt;
if (totalAmount < 11){
duplicateAmt = totalAmount
}else{
duplicateAmt = amountProccessed + dataResponse < totalAmount ? dataResponse : totalAmount - amountProccessed
}
duplicateWorkflow(totalAmount, omsid, duplicateAmt, amountProccessed);
amountProccessed += bulkAmount;
}
}
//用于创建工作流ajax调用的函数 – 成功处理程序正在更新用户.
function duplicateWorkflow( totalAmount, omsid, bulkAmount, amountProccessed){
amountProccessed += bulkAmount;
var url = '/portal/CreateWorkFlowServlet';
var errorString;
new Ajax.Request(
url, {
method: 'post',
parameters: {
totalAmount: totalAmount,
omsid: omsid,
bulkAmount: bulkAmount
},
async: false,
onSuccess: function(transport) {
var div = document.getElementById('progress');
if( amountProccessed > totalAmount){
div.innerHTML = totalAmount + ' out of ' + totalAmount + ' Processed ' ;
alert (totalAmount + 'Items successfully duplicated ')
}else{
div.innerHTML = amountProccessed + ' out of ' + totalAmount + ' Processed ' ;
}
},
onFailure: function(e) {
}
},
onException: function(e) {
}
},
});
}
解决方法:
根据经验,使用原始Javascript顺序化异步代码的方法是使用递归而不是for循环.
var urls = [ /*...*/ ];
function loop(i, onDone){
if(i >= urls.length){
//base case
onDone( theResultOfProcessingTheAjaxRequests );
}else{
Ajax.Request(urls[i], {
onsuccess: function(){
loop(i+1, onDone);
}
});
}
}
loop(0, function(result){
console.log("all done");
});
请注意,我将i转换为函数参数,以使其作用于循环函数.如果你愿意,你可以在外面声明它,就像你在for循环中所做的那样:
var urls = [ /*...*/ ];
var i = 0;
function loop(onDone){
//...
i = i+1;
loop(onDone);
}
另外,我在循环函数中添加了一个“onDone”回调,以帮助异步代码看起来更像同步版本.我们的想法是,通过使用返回回调,循环函数不需要知道调用它的函数以及它在完成其工作后应该跳转到的位置 – 最后,调用onDone(x)有点类似于执行返回x.当然,如果你愿意,你可以硬编码返回功能.
function afterajax(){
console.log("all done");
}
function loop(){
if(i >= urls.length){
afterajax();
}
//...
}
loop();
最后,像这样的编码递归循环有点烦人,并且有许多库提供了封装这些高级序列化和并行化模式的函数.特别是,错误处理(try-catch)特别难以通过回调手动完成.如果您正在进行任何更多的非特定的Async内容,我强烈建议您查看其中的一些库.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。