javascript - Promisiunile mele nu mai funcționează în jQuery 1.8
Acest fragment de cod a funcționat în 1.7.2 atât cu callback-uri de succes/eroare, cât și cu callback-uri de tip promisiune. În 1.8.2, callback-urile de succes/eroare încă funcționează, dar promisiunile nu. Bănuiesc că linia return dfd.promise(jqXHR); este problema, dar nu sunt sigur.
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
// Don't infinitely recurse
originalOptions._retry = isNaN(originalOptions._retry)
? Common.auth.maxExpiredAuthorizationRetries
: originalOptions._retry - 1;
// set up to date authorization header with every request
jqXHR.setRequestHeader("Authorization", Common.auth.getAuthorizationHeader());
// save the original error callback for later
if (originalOptions.error)
originalOptions._error = originalOptions.error;
// overwrite *current request* error callback
options.error = $.noop();
// setup our own deferred object to also support promises that are only invoked
// once all of the retry attempts have been exhausted
var dfd = $.Deferred();
jqXHR.done(dfd.resolve);
// if the request fails, do something else yet still resolve
jqXHR.fail(function () {
var args = Array.prototype.slice.call(arguments);
if (jqXHR.status === 401 && originalOptions._retry > 0) {
// refresh the oauth credentials for the next attempt(s)
// (will be stored and returned by Common.auth.getAuthorizationHeader())
Common.auth.handleUnauthorized();
// retry with our modified
$.ajax(originalOptions).then(dfd.resolve, dfd.reject);
} else {
// add our _error callback to our promise object
if (originalOptions._error)
dfd.fail(originalOptions._error);
dfd.rejectWith(jqXHR, args);
}
});
// NOW override the jqXHR's promise functions with our deferred
return dfd.promise(jqXHR);
});
Actualizare: Iată cererea mea ajax care eșuează:
$.ajax({
url: someFunctionToGetUrl(),
// works
//success: callback,
//error: ajaxErrorHandler
}).then(
[callback],
[errorback, ajaxErrorHandler]
);
};
Răspuns #1
Editare: Aceasta este o eroare în documentație, dar comportamentul este intenționat. API-ul s-a schimbat astfel încât deferred.then se comportă acum ca deferred.pipe și nu mai permite trecerea de array-uri, dar documentația nu a fost actualizată pentru a reflecta acest lucru.
Bug-uri asociate:
- github: deferred.then se comportă acum ca deferred.pipe, dar documentația este depășită
- Urmăritor de erori jQuery: Tichet #12765: deferred.then([SuccessArrayFuncs], failFunc) nu funcționează așa cum este descris
Soluția pe care o descriu la sfârșitul răspunsului meu inițial de mai jos se aplică în continuare.
Răspuns original:
Mi se pare o eroare jQuery. Dacă transmiți o singură referință de funcție ca prim argument, funcționează, dar nu dacă transmiți un array de funcții:
http://jsfiddle.net/tunDH/
Dar, documentația spune că un șir de funcții este perfect acceptabil:
doneCallbacks O funcție sau un șir de funcții, apelate atunci când Deferred este rezolvat.
Și ai dreptate. Funcționează cu jQuery 1.7: http://jsfiddle.net/tunDH/1/
O soluție alternativă ar fi să înfășurați toate apelurile funcțiilor dvs. într-o singură funcție, în loc să le puneți într-un tablou:
$.ajax({
url: someFunctionToGetUrl(),
// works
//success: callback,
//error: ajaxErrorHandler
}).then(
function(){
callback1.apply(this, arguments);
callback2.apply(this, arguments);
},
[errorback, ajaxErrorHandler]
);
http://jsfiddle.net/tunDH/2/
Probabil va trebui să faci același lucru și cu callback-urile de eroare, dar nu am testat asta.
