Я пытаюсь разобраться с отложенными / обещанными jQuery (используя v1.8 +).
После прочтения документации метод $.Deferred.then(...)
принимает doneFilter
и failFilter
в качестве аргументов для выполнения и возвращает обещание, которое мы можем использовать для цепочки следующим образом:
function doDefer() {
var $defer = $.Deferred();
doSomethingAsynchronous(
function () {
$defer.resolve();
},
function () {
$defer.reject();
}
);
return $defer.promise();
}
doDefer()
.then(function () {
return;
}, function () {
// second `then` not called
})
.then(function (b) {
// `b` is undefined, since first `then` returned without a value.
}, function () {
// fail end
});
Два вопроса:
- Почему цепочка выполнения останавливается в
doDefer()
, если она попадает в первую функциюfail
? Как я понимаю,then
возвращает$.Deferred.promise()
, как вторая цепочкаthen
соединяется (и выполняется).then
doneFilter / function / callback в первой цепочке всегда возвращается (?) - так почему / как jQuery обрабатываетfailFilter
по-другому? - Почему
then
возвращает$.Deferred.promise()
, аdone
/always
/fail
и т. Д. Возвращает$.Deferred
? Какая польза от этого (и почему она отличается отthen
)?
3 ответа
Почему цепочка выполнения останавливается в
doDefer()
, если она попадает в первую функциюfail
? Как я понимаю,then
возвращает обещание, как вторая цепочкаthen
соединяется (и выполняется).then
callback в первой цепочке всегда возвращается (?) - так почему / как jQuery по-разному обрабатываетfailFilter
?
Я не уверен, что понимаю вас правильно, но есть две вещи, которые вы должны знать:
then(done, fail)
только когда-либо выполняет один из своих обратных вызовов, в зависимости от того, выполнено или отклонено обещание, на которое они были прикованы.- обработка ошибок полностью прервана в jQuery. Обратный вызов вызывается, как и ожидалось, но обещание, возвращаемое вызовом
.then(…)
, не ведет себя Соответствует обещаниям / A + а> . Дождитесь jQuery 3.0, используйте правильную библиотеку обещаний ( поверх нее) или научитесь жить с ней.
Почему
then
возвращает$.Deferred.promise()
Потому что это обещание, которое разрешится с результатом соответствующего обратного вызова. Это не отложено, что вы можете решить сами. См. Также В чем разница между отложенным, обещанием и будущим в JavaScript?
… Пока
done
/always
/fail
и т. Д. Вернуть$.Deferred
?
Они не Они просто возвращают объект, к которому они были призваны, независимо от того, было ли это обещанием или отсрочкой.
Вы можете увидеть этот пример, его работа правильно:
function doDefer() {
var $defer = $.Deferred();
setTimeout( function(){
doSomethingAsynchronous(
function ( value ) {
// func1 - value is a random number
$defer.resolve( value );
},
function () {
$defer.reject();
}
);
}, 1000 );
return $defer.promise();
}
function doSomethingAsynchronous( func1, func2 ){
// random number 0-10
var random = Math.round( Math.random()*10 )
if( random > 5 ){
return func1.call( this, random );
}else{
return func2.call( this );
}
}
doDefer().then(function ( value ) {
// success
// make double of random
return value*2;
}, function () {
// fail when random number < 5
})
.then(function (b) {
// `b` is double of random number
console.log(b);
}, function () {
// fail end
});
Я надеюсь это поможет тебе
failHandler
остановит выполнение, как вы сказали. Ключ должен смотреть на цепь. Обработчик сбоя будет выполнен, только если обещание, к которому он был прикован, отклонено. Убедитесь, что вы смотрите на каждое звено в цепочке как отдельное обещание.
Цепочка может быть переписана следующим образом.
dfd1 = doDefer();
dfd2 = dfd1.then( success1, fail1 );
dfd3 = dfd2.then( success2, fail2 );
В этом примере success1
будет вызываться только в случае разрешения dfd1
. Если он отклонен, вместо него будет вызван fail1
, и цепь остановится.
Аналогично, success2
будет вызываться только в том случае, если разрешен dfd2
(другими словами, success1
возвращает значение или разрешает возвращенное обещание). Единственный способ выполнения fail2
- если dfd2
явно отклонен success1
(всплывающее сообщение об ошибке не работает в реализации jQuery).
Tl; dr - сбои не объединяются и, как сказал @Bergi, обработка ошибок в jQuery нарушена
Похожие вопросы
Связанные вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.