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 ユーザー権限管理の例について説明します。ご参考までに、詳細は以下の通りです...

Vue プロジェクトがページング効果を実現

ページング効果は、参考までにvueプロジェクトに実装されています。具体的な内容は次のとおりです。 1...

学生情報管理システムを実装するためのJavaScript+HTML

目次1. はじめに2. レンダリング3. コード4. 学生情報管理システムのメインインターフェース1...

Dockerコンテナにホストディレクトリへの書き込み権限がない場合の解決策

Docker コンテナを適用する場合、多くの場合、ホスト ディレクトリを Docker コンテナにマ...

CSS マージンの重複とその防止方法

2 つ以上のブロックレベル ボックスの垂直に隣接するエッジが重なり合っています。結果として得られる境...

Linux で Ceph 分散ソフトウェアをインストールして使用する方法に関するチュートリアル

目次序文1. 基本環境1. サービス配信2. ネットワーク構成(全ノード) 3. SSHパスワードフ...

Docker Composeのデプロイと基本的な使い方の詳しい説明

1. Docker Composeの概要Compose は、マルチコンテナ Docker アプリケー...

MySQL MyISAM デフォルト ストレージ エンジンの実装原則

デフォルトでは、MyISAM テーブルはディスク上に .frm (テーブル構造ファイル)、.MYD ...

Vueカスタム命令とその使用方法の詳細な説明

目次1. 指令とは何ですか? Vue でよく使われる組み込みの v ディレクティブv-if と v-...

PDO を使用して SQL インジェクションを防ぐ原理の分析

序文この記事では、SQL インジェクションを回避するために pdo の前処理メソッドを使用します。詳...

MySQL のタイムスタンプと日付時刻のタイムゾーンの問題によって生じる DTS の落とし穴の詳細な説明

目次MySQL で現在の時刻を表現するにはどうすればよいでしょうか?結論は確認するピットMySQL ...

小さな画像をクリックしたときに更新せずに大きな画像コードが表示されるようにLightboxを実現するためにCSSを使用する

小さな画像をクリックしたときに更新せずに大きな画像コードが表示されるようにLightboxを実現する...

バックエンドデータを取得するためのVue Elementフロントエンドアプリケーション開発

目次概要1. バックエンドデータの取得と処理2. インターフェース表示処理概要前回のエッセイ「ステッ...

Node.js のイベント モジュールに関する知識ポイントのまとめ

Node の研究と応用を通じて、NodeJS はシングルスレッド、イベント駆動型、非ブロッキング I...