web-dev-qa-db-ja.com

約束を同期的に検査することはアンチパターンですか?

ES6ネイティブPromiseでは、解決済み/保留中/失敗したかどうかを同期的にチェックしたり、値を抽出したりすることはできません。この機能が必要になることがあるため、手動でコーディングする必要があります。

これはアンチパターンと見なされますか?これが、この機能が標準から除外された理由ですか?

これは、この種の機能が役立つと思う状況です。

// the render method of a React component
// it will get triggered by other events other than the promise state change
render() {
  if (promise.resolved) {
    // render the result
  } else if (promise.rejected) {
    // render an error/reason
  } else {
    // render a loading message
  }
}
1
adrianton3

同期検査で私が知っている主な問題は、コードが特定のティック数内で解決または拒否するという約束に依存していない限り、完全に不要であるということです。これはまさに信頼すべきではない種類のことです。

たとえば、私はReactについて何も知りませんが、あなたの例は次のようなものに変更できると確信しています。

_this.text = "";

var promise = ...;
promise.then(function(result) {
    this.text = "Success: " + JSON.stringify(result);
}).catch(function(error) {
    this.text = "Error: " + JSON.stringify(error);
});

...

render() {
  // render the current value of this.text
}
_

renderメソッドは_this.text_の値がその特定の約束に依存していることを認識していないため、このバージョンの方が分離されていると主張することもできます。 ifステートメントを同期的に検査するという組み合わせ爆発を引き起こすことなく、_this.text_をいくつかの異なるpromiseの結果に依存させることが簡単にできるようになりました。

私が知っている同期検査の唯一の他の議論は、「 特定のコードパスでは、その時点で約束が果たされることが保証されていることが知られています-その場合、.thenを使用するのは非常に不便です。コールバックは常に非同期で呼び出されるため、promiseの値を取得します。 "promiseはreallyではないため、これらの場合でも.then()を使用します。 )_.then_ハンドラー(または_.spread_ハンドラーなど)に入るまで満たされることが保証されています。そうでなければ、私の議論が今日どれほど気密であっても、私のプログラムが将来壊れるための明白な方法を作成するだけだと仮定します。次のティックで呼び出されるハンドラーが深刻な問題である場合は、特定の操作が解決/拒否するために実行するティック数と実行しないティック数にすでに依存しています。これは、回避するのではなく、適切に修正する必要があります。

1
Ixrec

約束または未来の目的は、あなたが行って何か他のことをしている間(「別のスレッド」で)、約束が計算を追求できるようにすることです。他のことを終えて、値を調べるという約束に戻ったら、その値を待つことが期待されます(「他のことをする」が完了した後)。

プロミスがタスクを完了したらすぐにアクションを実行したい場合は、「プロミス」が完了したときに通知する方がよいと思います。つまり、イベントを使用します。

0
Robert Harvey

私はそれをアンチパターンとは呼びません、私はそれをばかげていると呼びます(ほとんどの場合)。

非同期作業を扱っているため、おそらくプレミスを使用しています。そうは言っても、そうでないと言うまでは、ステータスが保留中であると仮定する必要があります。

そうは言っても、おそらく、promiseイベント/コールバックを処理するコードのセクションもあります。デフォルトの状態(保留中)を設定し、成功イベントと失敗イベントをサブスクライブします。そして、これが本当に非同期のアクティビティである場合、promiseを同期的に検査するコードは、成功/失敗イベントに応答するコードと重複している可能性があります。そして、それが本当に非同期アクティビティである場合、その重複する非同期コードはおそらく実行されることさえありません。

0
svidgen