6

Re: https://github.com/tildeio/rsvp.js

doSomething() という関数があります。この関数は、しばらく何かを実行してから RSVP.Promise を返します。次に、成功と失敗のコールバックのチェーンが、返された promise に登録されます (以下のコードを参照)。私が期待した動作は、promise が満たされると、promise に登録された一連の成功コールバックが起動され、promise が拒否された (失敗した) 場合、一連の失敗コールバックが起動されるというものでした。

約束が果たされたときは期待どおりの動作が得られますが、約束が拒否されたときは期待したものとは異なる動作が得られます。つまり、成功コールバックは連鎖され、1 つの成功コールバックの出力が連鎖内の次の成功コールバックに渡されます。しかし、失敗のコールバックは連鎖していないようです。それらは、try/catch ブロックの catch とほとんど同じように動作します (以下のコードと出力を参照)。

誰かがこの動作を説明できますか? これは本当に動作するはずの方法ですか、それとも失敗コールバックのチェーンが登録されている拒否/失敗した promise を rsvp.js が処理する方法のエラーですか? 私は今、これを理解しようと Promises/A+ の仕様を読んでいますが、誰かが頭のてっぺんからこのことを知っているなら、あなたの説明を聞きたいです. 前もって感謝します。

jsfiddle: http://jsfiddle.net/rylie/VYSj7/2/

doSomething()  // returns an RSVP.Promise object
    .then(
        function(message) { console.log("then success 1: " + message); return "from success 1"; },  // success callback
        function(message) { console.log("then failure 1: " + message); return "from failure 1"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 2: " + message); return "from success 2"; },  // success callback
        function(message) { console.log("then failure 2: " + message); return "from failure 2"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 3: " + message); return "from success 3"; }   // success callback
    )
    .then(
        null,
        function(message) { console.log("then failure 4: " + message); return "from failure 4"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 5: " + message); return "from success 5"; },  // success callback
        function(message) { console.log("then failure 5: " + message); return "from failure 5"; }   // failure callback
    );

** 約束が果たされる (成功する) と、これは私が得て期待した出力です:

then success 1: Promise fulfilled!
then success 2: from success 1
then success 3: from success 2
then success 5: from success 3 

** promise が拒否された (失敗した) 場合、これは私が得る出力です:

then failure 1: Promise rejected!
then success 2: from failure 1
then success 3: from success 2
then success 5: from success 3 

**これは私が期待したものです(拒否/失敗した約束で):

then failure 1: Promise rejected!
then failure 2: from failure 1
then failure 4: from failure 2
then failure 5: from failure 4    
4

1 に答える 1

12

.then()1つ以上の引数を取り、メソッドを使用することさえ忘れてください。そうすれ.catchば、より理にかなっています。

Promise は、いくつかの同期コード構造への対応を提供しますが、これは、低レベルの.then(). あなたが探しているのは、基本的にコールバック/コールバック集約の配列ですが、それは約束のポイントではありません。

.catch(fn)と同じと考えてください.then(null, fn)

doSomething().then(function(val) {
    console.log(val);
}).catch(function(e) {
    console.error(e);
});

同期コードを並列化します (doSomething同期的に戻ると想像してください):

try {
    var val = doSomething();
    console.log(val);
}
catch(e) {
    console.error(e);
}

.catch複数のキャッチ(より読みやすいエイリアスであることを覚えておいてください.then(null, fn)

doSomething().then(function(val) {
    console.log(val);
}).catch(function(e) {
    return e;
}).catch(function(e){
    //Will not get here ever
    //because error thrown from doSomething()
    //was handled in the upper catch which doesn't trow
});

パラレル:

try {
    try {
        var val = doSomething();
        console.log(val);
    }
    catch(e) {
        //no need for explicit return e
    }
}
catch( e ) {
    //Will not get here ever
    //because error thrown from doSomething()
    //was handled in the upper catch which doesn't trow
}

したがって、 http://jsfiddle.net/VYSj7/3/を返す代わりにスローすることで、期待される結果を作成できることに気付くはずです。

.catch()IMO は promise ライブラリが提供する必須のメソッドであり、将来的に組み込みの Javascript promise にも含まれる予定です。ただし、そのようなメソッドが提供されていない場合は、次のことができます (または提供する必要があります。残念ながら、プロトタイプを使用しない実装があります)。

Promise.prototype.catch = function(fn) {
    return this.then(null, fn);
};

拒否が成就に変わるも参照してください。

于 2013-11-01T13:44:35.657 に答える