JavaScriptにおけるPromiseの使い方と注意点について(推奨)

JavaScriptにおけるPromiseの使い方と注意点について(推奨)

1. 約束の説明

Promise は、非同期操作の最終状態 (失敗または正常完了) とその結果の値を表すために使用される JavaScript の標準組み込みオブジェクトです。これにより、非同期操作の最終的な成功または失敗の理由をレスポンス ハンドラーに関連付けることができます。つまり、promise を通じて、非同期操作の終了後に実行する操作をカスタマイズできます。この場合、非同期メソッドは同期メソッドと非常によく似ており、戻り値もありますが、この戻り値は最終値をすぐに返すのではなく、promise を返します。promise の状態が変化すると、対応するハンドラーがトリガーされます。

約束は常に次のいずれかの状態になります: 1. 保留中 2. 履行済み 3. 拒否済み

promise が最初に作成されたときは、保留状態です。これは、満たされても拒否されてもいません。これは、promise サポートにまだ追加されていない関数をラップするために使用されます。ラップされた関数は、非同期操作関数になります。操作が終了すると、次の図に示すように、1 つは満たされ、もう 1 つは拒否される 2 つの分岐が存在します。満たされたプロミスは後続の then メソッドを呼び出しますが、拒否されたプロミスは then メソッドを呼び出すか、catch メソッドによってキャッチされます。 then メソッドが 2 つの状態の Promise をキャプチャできるのはなぜですか?ここでは詳しくは触れませんが、以下で詳しく紹介します。

2. プロセスの方向性を約束する

上の図は Promise のフローチャートです。左から右に、Promise が保留状態にある場合、2 つの分岐を経てそれぞれ then メソッドまたは catch メソッドに入ることがわかります。これらの c メソッドは両方とも promise を返します。この Promise も確定し、その後に then メソッドまたは catch メソッドがある場合は、何もなくなるまで後続の then と catch に入ります。

つまり、promise と then または catch は非同期操作のチェーン構造を形成できます。js のイベント ループ メカニズムと組み合わせると、js の利点がより明確になります。これは、現在でもブラウザーでよく見られます。

プロセスの特性に注意を払う必要があります。

1. Promiseはオブジェクトです。その転送の成功は戻り値ではなく、状態の確定(成功または失敗)に依存します。

2. then と catch は関数です。Promise の状態が変化すると、その Promise に対応する then または catch メソッドが呼び出されます。これら 2 つのメソッド自体は Promise を返し、返された Promise はこれら 2 つのメソッドに続く then または catch メソッドに影響を与えます。両方のメソッドの戻り値は promise である必要があります。

3. 約束の創造

Promiseオブジェクトは、 newキーワードとそのコンストラクターによって作成されます。このコンストラクターは、エグゼキューター関数と呼ばれる関数をパラメーターとして受け取ります。この「ハンドラー関数」は、 resolverejectという 2 つの関数をパラメーターとして受け入れます。非同期タスクが正常に完了して結果値を返すと、 resolve関数が呼び出されます。非同期タスクが失敗して失敗の理由 (通常はエラー オブジェクト) を返すと、 reject関数が呼び出されます。次に例を示します。

myFirstPromise = new Promise(function(resolve, reject){
 //非同期コードが正常に実行されると、resolve(...) を呼び出し、非同期コードが失敗すると、reject(...) を呼び出します。
 // この例では、setTimeout(...) を使用して非同期コードをシミュレートします。実際のコードは、XHR リクエストまたは HTML5 API メソッドである可能性があります。
 setTimeout(関数(){
  resolve("Success!"); //コードは正常に実行されます。
 }, 250);
});

myFirstPromise.then(function(successMessage){
 // successMessage の値は、上記のresolve(...) メソッドを呼び出すことによって渡される値です。
 // successMessage パラメータは文字列型である必要はありません。これは単なる例です。 console.log("Yay! " + successMessage);
});

4. 約束の利点

promise が表示されない場合、非同期コード ブロックを呼び出すと、順序を維持する方法がありません。非同期コードの結果を順序どおりにする必要がある場合、どのように実現すればよいでしょうか。

従来は、非同期コードをレイヤーごとに埋め込んで順番に実装するのが一般的でしたが、これではコードのメンテナンスが難しくなり、開発の難易度が上がっていました。

doSomething(関数(結果) {
 doSomethingElse(結果、関数(newResult) {
 doThirdThing(newResult, 関数(finalResult) {
  console.log('最終結果が得られました: ' + finalResult);
 }, 失敗コールバック);
 }, 失敗コールバック);
}, 失敗コールバック);

これは典型的なコールバック地獄です。先ほど紹介したPromiseを使うと、コードはメンテナンスしやすいチェーン構造になる。

5. thenメソッドによって返されるpromise型

Promiseが満たされるか拒否されると、返された関数は非同期的に呼び出されます (現在のスレッド ループによってスケジュールされます)。具体的な戻り値は以下の規則に従って返されます。コールバック関数のthen

  • 値が返された場合、 thenまでに返された Promise が承認状態となり、返された値は承認状態のコールバック関数のパラメータ値として使用されます。
  • 値が返されない場合、 thenまでに返された Promise は承認済み状態となり、承認済み状態のコールバック関数のパラメータ値はundefined
  • エラーをスローすると、 thenによって返された Promise は拒否され、スローされたエラーは拒否コールバック関数のパラメータ値として使用されます。
  • すでに承認済み状態にある Promise を返すと、 thenに返された Promise も承認済み状態になり、その Promise の承認済み状態のコールバック関数のパラメータ値が、返された Promise の承認済み状態のコールバック関数のパラメータ値として使用されます。
  • すでに拒否された Promise が返された場合、 then返された Promise も拒否され、その Promise の拒否コールバック関数のパラメータ値が、返された Promise の拒否コールバック関数のパラメータ値として使用されます。
  • pending Promise を返すthen 、返される Promise の状態も保留中になり、最終状態は Promise の状態と同じになります。同時に、最終状態になったときに呼び出されるコールバック関数のパラメータは、Promise が最終状態になったときのコールバック関数のパラメータと同じになります。

6. catch で捕捉されたエラー

Catch は、Promise の組み合わせで発生するエラーをキャッチできますが、キャッチできないエラーが 2 種類あります。

1. 解決されたエラーはキャッチできない

//解決される新しい Promise を作成します var p1 = Promise.resolve("calling next");

var p2 = p1.catch(関数 (理由) {
 //このメソッドは呼び出されません console.log("catch p1!");
 console.log(理由);
});

p2.then(関数 (値) {
 console.log("次のプロミスは onFulfilled"); /* 次のプロミスは onFulfilled */
 console.log(value); /* 次を呼び出す */
}, 機能(理由){
 console.log("次のプロミスは onRejected");
 console.log(理由);
});

2. 非同期関数でスローされたエラーはキャッチできない

なお、筆者は個人的な実践を通じて、promise でラップされた非同期関数が正常に実行された後、resolve メソッドと reject メソッドを明示的に呼び出して、後続の then メソッドと catch メソッドをトリガーする必要があることを発見しました。promise メソッドが非同期関数ではなく通常の同期関数をラップしている場合、同期コードが正しく実行されないと、reject メソッドが呼び出されなくても、後続の catch メソッドでエラーを捕捉できます。ただし、同期コードにエラーがなく、resolve メソッドを明示的に呼び出して転送しない場合は、後続の then メソッドはトリガーされません。

7. 高度な例

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
 <メタ文字セット="UTF-8">
 <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
 <title>ドキュメント</title>
 <スタイル>
  *{
   マージン: 10px;
  }
  html{
   幅: 100%;
   高さ: 100%;
  }
  体{
   幅: 100%;
   高さ: 100%;
   ディスプレイ:フレックス;
   アイテムの位置を中央揃えにします。
   コンテンツの中央揃え: 中央;
  }
  div.displaydatabox{
   幅: 300ピクセル;
   高さ: 300px;
   境界線の半径: 50px;
   テキスト配置: 中央;
   行の高さ: 300px;
   ボックスの影: 0 0 10px 2px 黒;
  }
  div.ボタン{
   幅: 100ピクセル;
   高さ: 50px;
   境界線の半径: 21px;
   境界線: 2px 実線オレンジ;
   行の高さ: 50px;
   テキスト配置: 中央;
   カーソル: ポインタ;
  }
 </スタイル>
</head>
<本文>
 <div class="button">作成</div>
 <div class="button">テキストを入力</div>
 <div class="button">消える</div>
 <script lang="javascript">
  buttonlist を document.querySelectorAll("div.button"); とします。
  本文を document.querySelector("本文") とします。
  ボタンリスト[0].onclick=関数()
  {
   div = document.createElement("div"); とします。
   div.className="ディスプレイデータボックス";
   body.appendChild(div);
  }
  ボタンリスト[2].onclick=関数()
  {
   div = document.querySelector("div.displaydatabox"); とします。
   body.removeChild(div);
  }
  ボタンリスト[1].onclick=関数(e)
  {
   p1 = new Promise((resolve, reject) => とします。
   {
    setTimeout(()=>{//setTimeout 関数を使用して非同期関数をシミュレートします。let div=document.querySelector("div.displaydatabox");
     div.textContent="これは Promise 実験です";
     //拒否(1);
     resolve(1); //resolveを呼び出すと最初に呼び出され、次に
    },2000);
   }).then(function(resolve){
    新しい Promise を返します ((resolve,reject)=>{
     console.log("これはステータスが確定していない Promise なので、後続の then メソッドは呼び出されません"); //resolve (1) //resolve または deny が呼び出されないため、ステータスは確定されません。呼び出されると 1 が出力され、ようやく呼び出されました!!
    })
   .then(関数(e){
    コンソールログ(e);
   });
   }).catch(関数(e)
   {
    console.log(e+"ブロックに入ることができません!!");
   }).then(()=>
   {
    console.log("ついに呼び出されました!!");
   })
  }
 </スクリプト>
</本文>
</html>

JavaScript における Promise の使い方と注意事項についてはこれで終わりです。JS における Promise の使い方に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript 非同期プログラミングにおける Promise の初期の使用法の詳細な説明
  • Node.js のコールバックを Promise に変換する方法
  • JS でカスタム Promise 操作の例を手書きする
  • node.js Promiseオブジェクトの使用例の分析
  • jsは再帰とpromiseを使用してデータを順番に要求します
  • Promise を使用して jsonp をカプセル化し、vue でデータを取得する
  • JS非同期プログラミングの深い理解 - Promise
  • JavaScript の async/await の原則と例の分析
  • JS スクリプトにおける async と defer の違いの詳細な説明
  • JSの非同期関数の意味と使用例のまとめ
  • Javascript非同期プログラミングの実装プロセスの詳細な説明async
  • JS で async/await を使用して非同期呼び出しを実装する方法
  • JS が async/await をジェネレータの構文糖と呼ぶ理由
  • JavaScript PromiseとAsync/Awaitの詳細な説明

<<:  node.js で Web サーバーを作成する手順の詳細な説明

>>:  uniAppエディタWeChatスライド問題について

推薦する

MySQL: MySQL 関数

1. 組み込み関数1. 数学関数ランド()丸め(数値) ceil(数値)階数(数値)ランダム丸め切り...

MySQL 8.0.14 のインストールと設定方法のグラフィックチュートリアル (一般)

MySQLサービス8.0.14のインストール(一般)の参考までに、具体的な内容は次のとおりです。イ...

Web デザイン TabIndex 要素

TabIndex は、Tab キーを押して、定義された TabIndex 要素を順番に取得し、各要素...

Element-ui の組み込み 2 つのリモート検索 (ファジークエリ) の使用方法の説明

問題の説明フロントエンドリモート検索やファジークエリと呼ばれる種類のクエリがあります。 Ele.me...

優れた UI (ユーザー インターフェース) デザイナーになるための 20 の道標

はじめに: インターフェイス デザイナーの Joshua Porter が自身のブログでこの記事を公...

HTML H タイトルタグの使用

H タグ、特に h1 タグの使用は常に議論の的となっている問題であり、私たちが研究する価値のある問題...

Docker を使用した nGrinder パフォーマンス テスト プラットフォームの導入プロセスの分析

nGrinderとは何ですか? nGrinder は、スクリプトの作成、テストの実行、監視、結果レポ...

MySQLインデックスを正しく作成する方法

インデックス作成は大学図書館の書誌インデックスの構築に似ており、データ検索の効率を向上させ、データベ...

CSSアニメーション属性キーフレームの詳細な説明

コラムを更新してからどれくらい経ったでしょうか?半年ですか?今年の後半は、まさに離陸、つまり文字通り...

純粋な CSS で DIV サスペンションを実装するサンプル コード (固定位置)

DIV フローティング効果 (固定位置) は CSS のみで実装されており、IE8、360、Fir...

CSS スタイルをプログラムで処理するためのサンプル コード

プログラム的アプローチの利点1. スタイルの分散を避けるためのグローバルコントロール2. シンプルな...

URL 書き換えモジュール 2.1 URL 書き換えモジュールのルール記述

目次前提条件テストページの設定書き換えルールの作成命名規則モードの定義アクションの定義設定ファイル内...

MySQL マルチテーブルクエリの具体例

1. SELECT句を使用して複数のテーブルをクエリするSELECT フィールド名 FROM tab...

vue3.0+echarts は 3 次元の縦棒グラフを実現します

序文: Vue3.0はechartsの3次元縦棒グラフを実装します結果: 実装手順: 1. echa...

Linuxにログインする際の文字セットの問題を解決する方法

文字セットエラーは常に存在するロケール: LC_CTYPE をデフォルト ロケールに設定できません:...