jQuery s ajax
возвращает объект Deferred
, который (сейчас) является обещанием согласно спецификации Promises / A +. Таким образом, вы можете перейти к использованию then
, который имеет семантику, которую вы ищете:
function foo(){
return $.ajax( ... )
.then(data => {
return /*...the transformed data...*/;
});
}
затем:
foo().then(data => { /*.. transformed data visible here ...*/ });
Примечание: Если код вызова foo
не может быть изменен, не беспокойтесь; done
также увидит обновленные данные. Но это должно быть then
в пределах foo
. Переключитесь на then
в коде, который также вызывает foo
, если вы можете, но если вы не можете, то все в порядке.
Вот живой пример использования then
в foo
и done
, когда позвонив: https://jsfiddle.net/tjcrowder/y1zh2xL4/
function foo(){
return $.ajax({
method: "POST",
url: "/echo/json/",
data: {
json: '{"key":"value"}',
delay: 1
}
})
.then(data => {
return {key: data.key.toUpperCase()};
});
}
// Just to show that `done` sees the updated data
foo().done(data => { console.log(data); });
В комментарии вы задали вопрос:
Дополнительный вопрос; Есть ли способ сделать такое же преобразование в цепочке ошибок?
Да! Обещания составлены таким образом, что два пути могут быть преобразованы на каждом уровне. Чтобы преобразовать отклонение, проходящее через цепочку, вы должны либо вернуть отклоненное обещание (return Promise.reject(x)
), либо бросить (throw x
). x
может быть любым, что вы хотите, хотя по соглашению обычно это Error
объект.
Так, например (https://jsfiddle.net/tjcrowder/y1zh2xL4/1/):
function foo(){
return $.ajax({
method: "POST",
url: "/echo/bad-url-not-on-jsfiddle",
data: {
json: '{"key":"value"}',
delay: 1
}
})
.then(data => {
return {key: data.key.toUpperCase()};
})
.catch(error => {
const myError = new Error("ajax failed");
myError.originalError = error;
myError.otherInformation = "whatever";
throw myError;
});
}
foo()
.done(data => { console.log(data); })
.fail(error => {
console.error(error);
console.error(error.otherInformation);
});