12

更新:この問題は、jQuery1.7と1.8の結果でした。1.7でプロミスを使用しないでください。プロミスは、内でプロミスを返すことと連鎖できないため.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関数をトリガーし、他のチェーンされたコールバックをスキップできるようにしたい。すべてのthenがトリガーされ、失敗がトリガーされない理由がわかりません。

私はNodeJSのQライブラリから来ているので、.then最初に試してみました。ただし、に変更し.pipeても効果はありません。

4

2 に答える 2

12

の値を再定義していない場合は、次のこと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。とてもかっこいい。これはjQuery1.8.0で追加された新機能であり、ドキュメントの更新が完了していない可能性があります。

于 2012-08-27T22:03:57.030 に答える
1

私見、あなたは何も連鎖していません。あなたの2番目は最初がに付けられ.thenているのと同じ約束に.then付けられています。

なんで?

が添付されているプロミスを変更するのではなく、then常に新しいプロミスを返すことに注意してください。副作用はありません。

例えば:

var promiseX = promiseA
                 .then(function() { return promiseB; })
promiseX.then(function() { return promiseC; });

promiseA アタッチされた後、その値は変更されませんthen; そのままにしておきます。

promiseX1番目の戻り値then、つまり、になりpromiseBます。

したがって、2番目thenは実際にはに接続されていpromiseBます。

そして、これはまさに@KevinBが彼の答えでしたことです。


もう1つの解決策は、新しいpromiseが返されるため、次のように関数.thenをチェーンできることです。.then

var promiseX = promiseA
                 .then(function() { return promiseB; })
                 .then(function() { return promiseC; });

今回は、1番目thenが付けられていますpromiseAが、2番目が付けられているのはどちらの約束thenですか?

あなたが正しい。それpromiseBは、ではありませんpromiseA。2番目は実際には1番目のthen戻り値に付加されているためです。thenpromiseB

そして最後に、2番目thenの戻り値がに割り当てられるpromiseXので、にpromiseX等しくなりpromiseCます。

OK、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();
于 2015-09-07T07:28:49.347 に答える