我有一系列异步操作,其响应必须同步才能运行最终操作。我使用延迟对象和 when()和 done()方法来实现此目的,但出于某种原因,当调用响应的第一个 resolve()时,始终执行done()中的最终操作。
这是我的代码,缩短了一点以使其更清晰:
// Central function that creates a Deferred object and returns a
// Promise from it. when the passed request is done,
// the Deferred is resolved
var getData = function(url, successFunction) {
var deferred = $.Deferred();
$.ajax({
url: url,
method: 'get',
dataType: 'json'
}).done(function(p) {
successFunction(p);
deferred.resolve(p);
}).fail(function(p){
deferred.reject(p);
});
return deferred.promise();
};
// Success actions to be called for each asynchronous request
var populateDestinations = function(data) {
// synchronous actions on DOM
};
var populateTaxes = function(data) {
// synchronous actions on DOM
};
var populatePayment = function(data) {
// synchronous actions on DOM
};
// Actions that return a Promise to control the resolution of
// all the deferred objects
var getCustomerDestinations = function(customerId) {
var url = $modal.data('url_destinations') + customerId;
return getData(url, populateDestinations);
};
var getCustomerTaxes = function(customerId) {
var url = $modal.data('url_taxes') + customerId;
return getData(url, populateTaxes);
};
var getCustomerPayment = function(customerId) {
var url = $modal.data('url_payment') + customerId;
return getData(url, populatePayment);
};
var populateFields = function() {
// final actions
};
$.when(getCustomerDestinations(customer_id),
getCustomerTaxes(customer_id),
getCustomerPayment(customer_id))
.done(function(){
populateFields();
});
正在调用populateFields(),其中一个"承诺"功能已解决,而不是在解析所有时。
知道我做错了什么吗?也许我还没有掌握Deferred对象的概念。
答案 0 :(得分:2)
你真的不需要使用任何延迟对象来跟踪ajax调用,而只需使用$.ajax
中$.when()
返回的promise对象。
JQUERY CODE:
var getData = function(url, successFunction) {
return $.ajax({
url: url,
method: 'get',
dataType: 'json'
}).then(function(p) {
successFunction(p);
},function(p){
//process error using error callback,
//just like success callbacks
});
};
我要处理单独的ajax调用,您可以使用.then()
代替.done()
& .fail()
,因为这些不会返回任何承诺对象,而不是.then()
来追踪.when()
中的承诺对象。
其余代码将按原样运行。
jQuery论坛说:
从 jQuery 1.8 开始,
deferred.then()
方法返回一个新的承诺,可以通过函数过滤延迟的状态和值,替换现在已弃用的deferred.pipe()
方法。doneFilter
和failFilter
函数会过滤原始延期的已解决/已拒绝状态和值。progressFilter
函数过滤对原始延迟的notify或notifyWith方法的任何调用。这些过滤函数可以返回一个新值,传递给promise.done()
或.fail()
回调,或者它们可以返回另一个可以通过它的可观察对象(Deferred,Promise等)解决/拒绝状态和承诺回调的价值。
反驳链接: