2016-06-18 10 views
2

私はTypescriptプロジェクトで興味深い問題に取り組んでいます(es6をターゲットにしています)。基本的に、いくつかの未定義の順序で多数の異なる一連のユーザー入力「ページ」を迅速に定義でき、前のページの結果が次のページの構築に何らかの影響を及ぼしているかもしれない。Typescript async /構造化の問題が発生する

私は、ユーザ入力が完了すると結果に解決する関数(ここではgetPromise1()など)で構築されたPromiseとして各ページを考えています。次に、async/awaitを使用してページを順番に作成します。

async process() { 
    let result1 = await this.getPromise1(); 

    let result2 = await this.getPromise2(result1.someData); 

    //etc... 

    this.commit(); 
} 

これはうまくいきますが、私はうんざりしました。ページの順序は、ユーザーの入力を介してどの段階でも取り消すことができます。そのため、構築はその時点で中止する必要があります。問題は、すべての段階でキャンセルをチェックすることは面倒で面白くなくなり、間違った方法を気に入ってくれて非常に強く感じます。

async process() { 
    let result1 = await this.getPromise1(); 
    if (result1.cancelled) { 
     this.revert(); 
     return; 
    } 


    let result2 = await this.getPromise2(result1.someData); 
    if (result2.cancelled) { 
     this.revert(); 
     return; 
    } 

    //etc... 

    this.commit(); 
} 

ここで私は間違っていますか?この種の設定に完全に間違ったパターンを使用していますか?この方法にアプローチするよりエレガントな方法はありますか?それとも、このようなことについてもっと良い方法があるのでしょうか?

+0

を使用し、例外を処理したくない場合は、 '非同期/ await'はES7の一部ではありません。 –

答えて

0

一つの可能​​な解決策は、あなたの「ページ」が拒否約束(すなわちthrowエラー)を持っているかもしれないので、あなたのprocess関数内でエラーをcatchすることができます。

class App { 

    async process() { 
     try { 
      let result1 = await this.getPromise1(); 

      let result2 = await this.getPromise2(result1.someData); 

      //etc... 

      this.commit(); 
     } catch (e) { 
      this.revert(); 
     } 
    } 

    async getPromise1() { 
     return {someData: 'foo'}; 
    } 

    async getPromise2({someData}) { 
     throw new Error('cancelled'); 
    } 

} 
+0

私はそれを考えましたが、例外的に例外をスローしないようにしたいと思っていました。それは間違っていると感じました。パフォーマンスに大きな影響を及ぼすと思います。 – Daniel

+0

@ダニエル合意したが、例外は「通常の」制御フローではなく、例外的なケースを処理するためにのみ使用されるべきである。残念ながら、私はOPのように手動で扱う以外の方法は考えられません。 : -/ –

0

これはシーケンスとあなた、あなたの約束を常にテストcancelledあるので、あなたはすべてのあなたの約束はまた

const seq: Prom[] = [this.getPromise1(), this.getPromise2(),...] 

for (let p of seq) { 
    const res = await p 
    if (res.cancelled) { 
     return this.revert() 
    } 
} 

シーケンスを実行し

interface Prom { 
    cancelled?: boolean 
} 

を拡張インターフェイスを作成することができます結果をcancelledに設定するのではなく、rejectにあなたの約束をしているなら、あなたはfaから利益を得ることができますPromise.allのIL速い動作:awaitを使用した場合

try { 
    await Promise.all([this.getPromise1(), this.getPromise2(),...]) 
catch(e) { 
    //a promise was rejected 
} 

処理の例外が実際に回避することはできません。 だからあなたはFYI then

Promise.all([this.getPromise1(), this.getPromise2(),...]).then(
    () => { //success }, 
    (reason) => { // failure } 
) 
+0

答えをありがとう!残念ながら、これは私が必要とする非常に重要な機能、すなわち次の約束の入力として1つの約束の結果を使用する能力を考慮していません。例外処理に関しては、例外を処理することはできませんが、例外的な状況では例外を投げることは避けてください。 – Daniel

関連する問題