[解決済み] キャッチの配置 BEFOREとAFTER then
質問事項
の違いがよくわかりません。
.catch
ネストされたプロミスの中で、BEFOREとAFTERの次に。
選択肢1.
test1Async(10).then((res) => {
return test2Async(22)
.then((res) => {
return test3Async(100);
}).catch((err) => {
throw "ERROR AFTER THEN";
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
選択肢2
test1Async(10).then((res) => {
return test2Async(22)
.catch((err) => {
throw "ERROR BEFORE THEN";
})
.then((res) => {
return test3Async(100);
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
各関数の動作は以下のとおりで、test1 は数値が
<0
test2 は数字が
> 10
でない場合、test3 は失敗します。
100
. この場合、test2が失敗しているだけです。
私はテスト2Asyncを実行して失敗させようとしましたが、BEFOREとAFTERの両方が同じように動作し、それはテスト3Asyncが実行されていないことです。誰か私に異なる場所にcatchを配置するための主な違いを説明することができますか?
各関数で私は
console.log('Running test X')
が実行されるかどうかをチェックするためです。
この質問は、私が投稿した前スレッドのために発生します。 ネストされたコールバックをプロミスに変換するには? . これは別の問題であり、別のトピックを投稿する価値があると思います。
解決方法は?
つまり、基本的には、この2つの違いは何かということですね(ここで
p
は以前のコードから作成されたプロミスです)。
return p.then(...).catch(...);
そして
return p.catch(...).then(...);
p が解決するときと拒否するときのどちらにも違いがありますが、その違いが問題になるかどうかは
.then()
または
.catch()
ハンドラによって行われます。
が発生するとどうなるか?
p
が解決します。
最初のスキームでは
p
が解決されると
.then()
ハンドラが呼ばれる。 もし、その
.then()
ハンドラは値を返すか、最終的に解決される別のプロミスを返します。
.catch()
ハンドラはスキップされます。 しかし、もし
.then()
ハンドラが投げたり、最終的に拒否されるプロミスを返したりすると
.catch()
ハンドラは、元のプロミスが拒否された場合にも
p
で発生したエラーだけでなく
.then()
ハンドラです。
2番目のスキームでは
p
が解決されると
.then()
ハンドラが呼ばれる。 もし、その
.then()
ハンドラが投げるか、最終的に拒否するプロミスを返せば
.catch()
ハンドラはそれを捕らえることができません。なぜなら、チェーンの中でハンドラの前にいるからです。
つまり、これが違いその1です。 もし
.catch()
ハンドラが AFTER にある場合、そのハンドラの内部で発生したエラーも捕捉することができます。
.then()
ハンドラです。
が発生するとどうなるか?
p
を拒否します。
さて、最初のスキームにおいて、もし約束事である
p
が拒否した場合
.then()
ハンドラはスキップされ
.catch()
ハンドラは期待通りに呼び出されます。 このとき
.catch()
ハンドラによって、最終的に何が返されるかが決まります。 もし、単に
.catch()
ハンドラや、最終的に解決するプロミスを返した場合、エラーを "処理" して正常に返したため、プロミスチェーンは解決した状態に切り替わります。 の中で拒否されたプロミスを投げたり返したりすると、プロミスの連鎖は解決された状態に切り替わります。
.catch()
ハンドラでは、返されたプロミスは拒否されたままです。
2番目の方式では、プロミス
p
が拒否された場合
.catch()
ハンドラが呼び出されます。 通常の値や、最終的に解決するプロミスを返した場合は
.catch()
ハンドラ(つまりエラーを処理する)では、プロミスの連鎖が解決済みの状態に切り替わり、さらに
.then()
ハンドラの後に
.catch()
が呼び出されます。
というわけで、違いその2です。 もし
.catch()
ハンドラがBEFOREであれば、エラーを処理することができます。
.then()
ハンドラを呼び出すことができます。
いつwhichを使うか。
を1つだけ使用したい場合は、最初のスキームを使用します。
.catch()
ハンドラで、元のプロミスである
p
または
.then()
ハンドラから拒否され
p
はスキップする必要があります。
.then()
ハンドラを使用します。
元のプロミスのエラーをキャッチできるようにしたい場合は、2番目のスキームを使用します。
p
を実行し、(条件次第では)プロミスの連鎖を解決済みとして継続させることができるかもしれません。
.then()
ハンドラを使用します。
もう一つの選択肢
に渡すことができる両方のコールバックを使用する、もう一つのオプションがあります。
.then()
というように
p.then(fn1, fn2)
のうちの1つだけが保証されます。
fn1
または
fn2
が呼ばれることはありません。 もし
p
が解決されると
fn1
が呼び出されます。 もし
p
が拒否された場合
fn2
が呼び出されます。 での結果の変更はありません。
fn1
にすることはできません。
fn2
が呼び出されたり、その逆もあります。 ですから、ハンドラの中で何が起ころうとも、2つのハンドラのうち1つだけが確実に呼び出されるようにしたい場合は
p.then(fn1, fn2)
.
関連
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] package.jsonのチルダ(~)とキャレット(^)の違いは何ですか?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] URLを新しいタブで開く(新しいウィンドウではない)
-
[解決済み] npm package.jsonファイルのdependencies, devDependencies, peerDependenciesの違いは何ですか?
-
[解決済み] アップロード前に画像をプレビューする
-
[解決済み] Node.jsのmodule.exportsの目的と使い方を教えてください。
-
[解決済み】PromiseとObservablesの違いは何ですか?
-
[解決済み] .then()チェーンで以前のプロミス結果にアクセスするにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
fetch ネットワークリクエストラッパーの説明例
-
vue3.0プロジェクトのアーキテクチャを構築するための便利なツール
-
JavaScriptのクロージャの説明
-
VUEグローバルフィルターの概念と留意点、基本的な使い方
-
[解決済み】最大呼び出しスタックサイズ超過エラー
-
[解決済み】JavaScriptの配列でforEachが関数でない不具合
-
[解決済み】TypeError: Router.use() はミドルウェアの関数を要求しているが、Object を取得した。
-
[解決済み] 期待される代入または関数呼び出し: 未使用式なし ReactJS
-
[解決済み] Web API エラー - このリクエストはブロックされました; コンテンツは HTTPS で提供されなければなりません
-
[解決済み】JavaScript TypeError: null のプロパティ 'style' を読み取ることができない