Попытка сломать цепочку обещаний jQuery с помощью .then,.fail и .reject
Обновление: эта проблема была результатом jQuery 1.7 vs 1.8. Никогда не используйте promises в 1.7 beacuse, они не связаны с возвратом обещания внутри .then
. 1.8 похоже, что они не испортили его.
http://jsfiddle.net/delvarworld/28TDM/
// make a promise
var deferred = $.Deferred();
promise = deferred.promise();
// return a promise, that after 1 second, is rejected
promise.then(function(){
var t = $.Deferred();
setTimeout(function() {
console.log('rejecting...');
t.reject();
}, 1000);
return t.promise();
});
// if that promise is successful, do this
promise.then(function() {
console.log('i should never be called');
})
// if it errors, do this
promise.fail(function() {
console.log('i should be called');
});
deferred.resolve();
Ожидаемое: "Я должен быть вызван"
Фактически: "я никогда не должен называться"
Проблема. Я хочу связать обратные вызовы и любой из них сможет разбить цепочку и запустить функцию fail
и пропустить другие связанные вызовы. Я не понимаю, почему все thens запускаются, и сбой не запускается.
Я иду из библиотеки NodeJS Q, поэтому сначала попробовал его с .then
. Однако изменение его на .pipe
не влияет.
Ответы
Ответ 1
Вы не переопределяете значение promise
, попробуйте следующее:
http://jsfiddle.net/28TDM/1/
var deferred = $.Deferred();
promise = deferred.promise();
promise = promise.then(function(){
var t = $.Deferred();
setTimeout(function() {
console.log('rejecting...');
t.reject();
}, 1000);
return t.promise();
});
promise.then(function() {
console.log('i should never be called');
})
promise.fail(function() {
console.log('i should be called');
});
deferred.resolve();
По-видимому, он работает, как вы думали, он сделал, он просто не документирован https://api.jquery.com/deferred.then. Очень круто. Это новая функциональность, добавленная в jQuery 1.8.0, более вероятно, что они просто не будут обновлять документацию.
Ответ 2
ИМХО, ты ничего не цепляешь. Ваш второй .then
прикреплен к тому же обещанию, что и первый .then
прикреплен к.
Почему?
Обратите внимание, что then
всегда будет RETURN новым обещанием, а не изменяет обещание, к которому оно привязано. Он не имеет побочного эффекта.
Например:
var promiseX = promiseA
.then(function() { return promiseB; })
promiseX.then(function() { return promiseC; });
promiseA
не изменит свое значение после присоединения then
; он будет сохраняться, как есть.
promiseX
будет возвратным значением 1-го then
, то есть promiseB
.
Итак, второй then
фактически привязан к promiseB
.
И это именно то, что @Kevin B сделал в своем ответе.
Другое решение состоит в том, что, поскольку .then
вернет новое обещание, вы можете связать функции .then
, как показано ниже.
var promiseX = promiseA
.then(function() { return promiseB; })
.then(function() { return promiseC; });
На этот раз 1-й then
прикреплен к promiseA
и догадывается, к какому обещанию привязан второй then
к?
Ты прав. Это promiseB
, а не promiseA
. Поскольку второй then
фактически привязан к возвращаемому значению 1-го then
, т.е. promiseB
.
И, наконец, 2 then
возвращает значение promiseX
, поэтому promiseX
равно promiseC
.
Хорошо, вернитесь к вопросу OP. Следующий код - это мой ответ.
var deferred = $.Deferred();
promise = deferred.promise(); // this is the first promise
promise.then(function(){ // callbacks for 1st promise
var t = $.Deferred();
setTimeout(function() {
console.log('rejecting...');
t.reject();
}, 1000);
return t.promise(); // this is the 2nd promise
// return $.Deferred().reject(); // To reject immediately.
}).then(function() { // callbacks for 2nd promise
console.log('i should never be called');
}, function() {
console.log('i should be called');
})
deferred.resolve();