2013-10-30 3 views
6

日時:https://github.com/tildeio/rsvp.jsはどのようにハンドルが失敗コールバックのチェーンとの約束を拒否rsvp.js

私は しばらく少しのために何かをした後、RSVP.Promiseを返すのdoSomething(と呼ばれる機能)を持っています。次に、返された約束に成功と失敗のコールバックのチェーンが に登録されます(下記のコードを参照)。私が期待した動作 は、約束が満たされていれば、 で登録された成功コールバックのチェーンが起動され、約束が拒否された場合(失敗)、 失敗コールバックのチェーンが起動されます。

約束が満たされたときに期待される動作が得られますが、約束が拒否されたときに期待したものとは異なる の動作が発生します。つまり、 成功コールバックがチェーンされ、1つの成功コールバックの出力がチェーンの次の成功コールバック に渡されます。しかし、失敗コールバック はチェーンされていないようです。それらはtry/catchブロックのキャッチのように振る舞います( のコードと出力を参照してください)。

誰かがこの現象を説明できますか?これは本当に動作すると思われますか、または は、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 

**約束が拒否された(失敗しました)、これは私が得る出力です:

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

**これは私が期待していたものですあなただけの.then()がさらに1つの以上の引数を取ることを忘れて.catch方法を使用して、それはより多くの意味を行いますする必要があり

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

答えて

11

:/約束を)失敗しました。

プロミスはいくつかのシンクコード構成に対応していますが、これはあくまでもローレベルの.then()を持っているときにはあまり表示されません。あなたが探しているのは、基本的にコールバック/コールバック集約の配列ですが、それはまったく約束のポイントではありません。.then(null, fn)と同じ.catch(fn)

思う:

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

は同期コード(同期doSomethingリターンを想像する)のParallels:

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 
}); 

のParallels:

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提供する約束ライブラリに不可欠な方法であるともなります将来Javascriptの組み込み規約に組み込まれています。

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

も参照してくださいrejection turns into fulfillment

+0

ニース説明、Esailija:このような方法が提供されていない しかし、もし、あなたがすることができます(またはあるべき、残念ながらプロトタイプを使用しない実装があります)!ありがとう。 – RBR