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スライド問題について

推薦する

HTML 順序なしリスト 箇条書き 画像を使用した CSS の記述

少なくとも 5 冊のベストセラー書籍の順序なしリストを含む HTML ページを作成します。各書籍の前...

ページ切り替え効果を実現するJSコード

この記事の例では、ページ切り替え効果を実現するためのJSコードの具体的なコードを参考までに共有してい...

Nginx タイムアウト設定の詳細な説明

最近、プロジェクトで nginx を使用し、バックエンドで Java を使用しました。バックエンドで...

JavaScriptプロトタイプチェーンの詳細な説明

目次1. コンストラクタとインスタンス2. プロパティプロトタイプ3. プロパティ __proto_...

Linuxオンラインソフトウェアgccをオンラインでインストールする方法

Linux オンラインインストール関連コマンド: yum install: すべてインストールyum...

JSは画像の滝の流れの効果を実現します

この記事では、画像ウォーターフォールフローを実現するためのJSの具体的なコードを参考までに共有します...

Centos8 は kdc 暗号化に基づいて nfs を構築します

目次構成nfs サーバー (nfs.skills.com) nfs クライアント (client.s...

CentOS での MySQL ログイン 1045 問題を解決する

アプリケーション全体を CentOS にデプロイする必要があるため、当然ながらデータベース操作は不可...

Vueカスタムテーブル列実装プロセス記録

目次序文レンダリングsetTable コンポーネント使用結論序文フォームを使用して PC 側のプロジ...

MySQL でストアド プロシージャを作成し、ループでレコードを追加する方法

この記事では、例を使用して、MySQL でストアド プロシージャを作成し、ループでレコードを追加する...

MySQL 空間データストレージと関数

目次1. データ型1. MySQL空間データとは何か2. GeoJSONとは3. 空間データ型のフォ...

Vue 仮想 DOM クイックスタート

目次仮想DOM仮想DOMとは何か仮想DOMの役割Vue の仮想 DOM vノードvNodeとはvNo...

JavaScript によるダイナミッククリスマスツリーの詳細な説明

目次1. CSS のみを使用して作成したアニメーションのクリスマスツリー2. CSS のみを使用して...

Linux で特定のプログラムを見つけるための whereis の例の詳細な説明

Linuxは特定のプログラムを見つけますwhereis コマンドは主にプログラム ファイルを検索し、...

MySQLでデータベースのインストールパスを表示する方法

mysql コマンドを使用して、mysql のインストール パスを表示できます。 # 次の 2 つの...