2016-08-07 3 views
0

私は約束を呼び出す関数を持っています。成功または失敗の場合、私は約束を返す以上のデータを返したいと思います。try/catchの約束事を適切な方法でブロックしていますか?

私は、これはうまくいくかもしれないと思った:

function foo() { 
    const extra = 'bar' 
    return thepromise().then((res) => { 
    return { 
     result: res, 
     data: extra 
    } 
    }, (err) => { 
    // this will not happen if an error is thrown in the called promise 
    return { 
     result: res, 
     data: extra 
    } 
    }) 
} 

foo().then((res) => { }, (err) => { // error result ends up here }) 

しかし、これは動作しません。 thepromiseにエラーがスローされた場合、catchブロックは呼び出されず、代わりにfoo()のcatchブロックが呼び出されます。

これを処理する適切な方法は何ですか?私は、try/catchブロックで成功していますが、私はこれが最善のアプローチであることを確認していない:例外またはエラーの任意の並べ替えを投げるべきではない約束を返すように設計された機能

function foo() { 
    const extra = 'bar' 
    return new Promise((resolve, reject) => { 
    try { 
     return thepromise(p) 
    } catch (e) { 
     reject(e) 
    } 
    }) 
    .then(function(res) { 
    return { 
     result: res, 
     data: extra, 
     status: 'success' 
    } 
    }, function(err) { 
    return { 
     result: err, 
     data: extra 
     status: 'error' 
    } 
    }) 
} 
+1

あなたの最初の例が私のために働きます(変数名まで - 最初のハンドラには存在しない "res"変数を参照しています。これは "err" 、 "res"ではない)。どのようなエラーが表示されますか? –

+0

'thepromise'はエラーを投げてはいけません。そうであれば、約束を正しく使用しておらず、拒否された約束を返すように書き直さなければならない。 – zzzzBov

答えて

0

にエラーをthrowことができます。

import Promise from 'bluebird'; 

// ... 

return Promise 
    .try(thepromise) 
    .then(res => ({ 
    result: res, 
    data: extra 
    }) 
    .catch(err => ({ 
    result: res, 
    data: extra 
    }); 
1

もしそうであれば、それはバグであるとみなされるべきです。

バグのあるメソッドを修正するには、例外をスローするのではなく、返された約束を拒否します。


他のユーザーのAPIを使用しているなど、潜在的なバグを修正することができない場合があります。これが当てはまる場合、最初に最も重要なことは、オリジナルの著者にバグを報告し、根本的な問題を修正できるようにすることです。

問題を報告した後、あなたが問題を解決するために、簡単なユーティリティでバギーメソッドをラップすることができます

function fixBrokenPromise(promise/*, args...*/) { 
    var args = Array.prototype.slice.call(arguments, 1), 
     ret; 
    try { 
    ret = promise.apply(null, args); 
    } catch (ex) { 
    ret = Promise.reject(ex); 
    } 
    return ret; 
} 

としてこれを呼び出すことができます。エラーがで取り扱わ考えられている

fixBrokenPromise(thepromise/*, args you want to pass to thepromise */) 
    .then(...resolve..., 
     ...reject...); 
0

.catch()であり、これは、約束された約束を返して.then()に戻す。あなたはbluebirdはあなたが必要なものだけでないtry methodを持って、次の.catch()

function foo() { 
 
    const extra = 'bar' 
 
    return thepromise().then((res) => { 
 
    return { 
 
     result: res, 
 
     data: extra 
 
    } 
 
    }, (err) => { 
 
    throw new Error(JSON.stringify({ 
 
     result: err || "no rejection reason provided", 
 
     data: extra 
 
    })) 
 
    }) 
 
} 
 

 
var thepromise =() => Promise.reject(); 
 

 
foo().then(data => console.log("fulfilled", data)) 
 
.catch(err => console.log("catch", JSON.parse(err.message)))
あなたは約束に拡張を楽しまために喜んでいる場合

+0

インナーキャッチブロックが呼び出されることはありませんので、私はそれを行うことはできません。 – cyberwombat

+0

_ "インナーキャッチブロックは決して呼び出されないので、私はそれをすることはできません。"両方の '.catch()'関数は、最初の '.catch()' 'throw'sのところで呼び出されます。更新されたポストを参照してください – guest271314

+0

@Yashua最初の '.catch()'から連鎖、2番目の '.then()'にデータを渡して、解決された約束または連鎖、2番目の '.catch()'をエラーとして渡しますか?または約束を拒否? – guest271314

関連する問題