顺序异步调用很严重。有没有更易读的解决方案?
问题是这很难理解:
ajaxOne(function() {
// do something
ajaxTwo(function() {
// do something
ajaxThree()
});
});
其中匿名函数是在服务器响应上调用的回调。
我正在使用第三方 API 进行 AJAX 调用,所以我需要一个通用的解决方案。
顺序异步调用很严重。有没有更易读的解决方案?
问题是这很难理解:
ajaxOne(function() {
// do something
ajaxTwo(function() {
// do something
ajaxThree()
});
});
其中匿名函数是在服务器响应上调用的回调。
我正在使用第三方 API 进行 AJAX 调用,所以我需要一个通用的解决方案。
函数式编程来拯救!jsdeferred让您可以像这样编写示例:
next(ajaxOne).next(ajaxTwo).next(ajaxThree).error(function(e){alert('An error happened:' + e)})
每个“顺序”ajaxOne/Two/Three 函数都接收其前身的返回结果作为参数。如果您需要传递额外的参数,您可以在调用 ajax 链之前将它们暴露在一个全局对象中。
首先我必须承认,我对 JavaScript 比较陌生,但是我最近在使用 jQuery ajax 函数时遇到了同样的问题。我必须通过 POST 以特定顺序将几个文档上传到服务器。嵌套所有回调会产生完全混乱的代码。阅读答案后,我想到了一个解决方案,并提出了一个对我有用的解决方案。它仅使用一个带有 switch 子句的函数来区分不同的回调调用:
var callback = function(sCallIdentifier, callbackParameters){
switch(sCallIdentifier){
case "ajaxOne":
doYourStuff(callbackParameters); //do your stuff for ajaxOne
ajaxTwo(function(newCallbackParameters){
/*define a anonymous function as actual method-callback and pass the call-identifier, together with all parameters, to your defined callback function*/
callback("ajaxTwo", newCallbackParameters);
});
break;
case "ajaxTwo":
doYourStuff(callbackParameters);
ajaxThree(function(newCallbackParameters){
callback("ajaxThree", newCallbackParameters);
});
break;
case "ajaxThree":
doYourStuff();
break;
}
});
如果这不是一个好主意,请告诉我。正如我所说,我不是 JavaScript 专家,但它对我来说工作得很好。
最好的,勒内
编辑:
一段时间后,我发现Promises是解决这个问题的更好方法。
如果你只有一个嵌套函数,可以保持原样,但是如果你有多个嵌套调用,你应该考虑在单独的方法中编写这些回调,并从嵌套函数中调用它......
ajaxOne(function(result) { handleAjaxOneCallback(result, someExtraNeededArg); } );
function handleAjaxOneCallback(result, someExtraNeededParam) {
// do something
ajaxTwo(function(result) { handleAjaxTwoCallback(result, myFoo, myBar); });
}
function handleAjaxTwoCallback(result, foo, bar) {
// do something
ajaxThree(/* ... */);
}
如果您不需要回调中的闭包范围,您可能不需要,您可以将回调放入单独的函数中并按它们的名称调用它们。喜欢:
var ajaxOne = function() {
doTheAjax(callbackOne);
}
var callbackOne = function() {
//funny things ...
doTheAjax(callbackTwo);
}
var callbackTwo = function() {
//even more funny things ...
}