2017-01-18 6 views
3

に拒否ES2017非同期/待つと素晴らしいパターンがあるの取り扱いしかし、私は非同期的に、私が再割り当てから保護したい値を得たいとします(データベースセッションなど)。しかし、私はまだ非同期/待機パターンを使用したいと思います。はエレガント `await`ed Javascriptを約束

constのブロックがスコープされているので、以下は動作しません:もちろん

async function() { 
    try { 
    const result = await get_session() 
    } catch (err) { 
    console.log(`This block should catch any 
     instantiation errors.`) 
    return false 
    } 
    // Can't get at result here because it is block scoped. 
} 

はあなたがtryブロック内の関数の残りの部分を実行することもできますが、その後、あなたは秋聞かせすべきことであるが、捕まるのエラーを危険にさらしますどこかで(たとえば、私はテストの失敗のようなエラーがテストスイートに落ちる必要があるが、ドライバのインスタンス化を自分自身で処理する必要があるテストを書くこのチャレンジを打った。おそらく、私はここで何らかのアンチパターンに陥るだろう。 )

簡単な答えは明らかにここでそのパターンを使用しないことです。代わりに約束とコールバックを使用してください。または、varを使用し、ブロックスコープconstletを避けてください。しかし、私は他の考慮事項のための再割り当て保護とブロックスコープの利点が好きです。

[質問]:Is there a way to wrap an await/async try/catch block to every function?潜在的な解決策の1つと思われますが、確かにtry/catchのようにわかりません。 try/catchが機能の範囲を壊しておらず、try/catchブロック内のreturnを使用できるという事実は、より手続き的なロジックを非同期コードに持っていくという精神に沿っているように思えます。

理想的には、const x = await y() catch (err)またはconst x = await y() || failのような何かをしたいと思います。しかし、私は構文的に正しいです同様の流れでは何も考えることはできません。

UPDATE: 別の代替の下@ jmar777によって示唆されるようです:

おそらく私は実際には、これらの最後の2つの例に見つけた最も近い
const x = await y().catch(() => {/*handle errors here*/}) 

。しかし、上記の例では、ダウンストリーム実行をブロックするreturnスコープが壊れています。何が物事を扱うかのような素晴らしい同期的な方法です。

各ソリューションにはトレードオフがあります。

さまざまなアプローチを見ても興味深い質問がありましたので、機能ブロックの上部にある変数をマニュアルでletで手作業で解決しました(jmar777の答えに記載されています)。今。

+1

async/awaitはES7(ES2016)の一部ではありません。今年のリリース、ES2017の一部になる予定です。 –

答えて

3

constのメリットについて誤解を招くことがあります。 const宣言を使用して値を代入すると、その値は不変ことはない、それは単にその定数の値を変更または再宣言することができないことを意味:

CONST宣言は、値に読み取り専用の参照を作成し。保持している値が不変であることを意味するものではなく、変数識別子を再割り当てできないということだけではありません。例えば、コンテンツがオブジェクトである場合、オブジェクト自体が依然として変更可能であることを意味する。

async function() { 
    let result; 

    try { 
    result = await get_session() 
    } catch (err) { 
    console.log(`This block should catch any 
     instantiation errors.`) 
    } 

    // do whatever else you need with result here... 
} 

代替は、あなたドンそのコードを再構築するために、次のようになりますあなたの例では(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

、おそらく手動でのtry/catchのごresult結合外側を巻き上げオフ最高ですtry/catchに頼る必要はありません。たとえば:

async function() { 
    const result = await get_session().catch(someRejectionHandler); 

    // do whatever else you need with result here... 
} 

はちょうどあなたの下流のコードが正常get_session()が拒否された、とresultが成功した応答に基づいて初期化されていない場合を処理する必要があることに注意してください。これはあなたの最初の例と変わりありませんが、コードをスキャンするときにはあまり明らかではないかもしれません。

+0

ああ、私は 'const'というよりむしろ '不変'の意味を誤解していたと思う。混乱を解消するために質問を編集します。また、元のコードの中で、私はダウンストリームの実行を防ぐために 'catch'ブロックに' return'を書いていました。私は擬似コードを更新して一致させます。 'catch 'の内部から戻ることができるのは、コールバックで' .catch'するのが好きな理由の1つです。 'async/await'と一線を画しているようです。あなたの吊り上げの解決策は、私がコードを稼働させるために取り上げたものです。まだconstを持っているのはうれしい。 –

+0

あなたの試行でreturn文が必要ないのですか? – PositiveGuy

+0

@PositiveGuyエラー処理ロジックは問題の対象ではありませんでした。これは実際には、 'result'をより高い範囲に手動で巻き上げることを実証するためのtry/catchスタブです。 – jmar777