序文Web プロジェクトの開発プロセスでは、繰り返しリクエストが発生するシナリオに頻繁に遭遇します。システムが繰り返しリクエストを処理できない場合、システムでさまざまな問題が発生する可能性があります。たとえば、POST リクエストが繰り返されると、サーバー側で 2 つのレコードが生成される場合があります。では、重複したリクエストはどのように発生するのでしょうか?ここでは、2 つの一般的なシナリオを示します。
重複リクエストがどのように生成されるかがわかったので、それが何らかの問題を引き起こす可能性があることもわかりました。次に、アバオ兄弟は Axios を例に、重複リクエストの問題を解決する方法を説明します。 1. リクエストをキャンセルする方法Axios は、ブラウザと Node.js 環境の両方をサポートする Promise ベースの HTTP クライアントです。これは優れた HTTP クライアントであり、多数の Web プロジェクトで広く使用されています。ブラウザ環境では、Axios の基盤となるレイヤーは XMLHttpRequest オブジェクトを使用して HTTP リクエストを開始します。リクエストをキャンセルしたい場合は、XMLHttpRequest オブジェクトの abort メソッドを呼び出してリクエストをキャンセルできます。 xhr = new XMLHttpRequest(); xhr.open("GET", "https://developer.mozilla.org/", true); xhr.send(); タイムアウトを設定します(() => xhr.abort(), 300); Axios の場合、Axios が提供する CancelToken を通じてリクエストをキャンセルできます。 CancelToken は axios.CancelToken に置き換えられます。 const ソース = CancelToken.source(); axios.post('/user/12345', { 名前: 'semlinker' }, { キャンセルトークン: ソース.token }) source.cancel('ユーザーによって操作がキャンセルされました。'); // キャンセル要求、パラメータはオプションです さらに、次に示すように、CancelToken コンストラクターを呼び出して CancelToken を作成することもできます。 CancelToken は axios.CancelToken に置き換えられます。 キャンセルする; axios.get('/user/12345', { キャンセルトークン: 新しいキャンセルトークン(関数executor(c) { キャンセル = c; }) }); cancel(); // リクエストをキャンセルする CancelToken を使用して Axios でリクエストをキャンセルする方法がわかったので、CancelToken は内部でどのように動作するのでしょうか?まずこの質問を覚えておいてください。後で、アバオ兄弟がCancelTokenの秘密を明かします。次に、重複リクエストを判別する方法を分析しましょう。 2. 重複リクエストの判定方法リクエストメソッド、リクエスト URL アドレス、リクエストパラメータが同じ場合、リクエストは同じであるとみなすことができます。したがって、リクエストが行われるたびに、現在のリクエストのリクエスト メソッド、リクエスト URL アドレス、リクエスト パラメータに基づいて一意のキーを生成し、リクエストごとに専用の CancelToken を作成し、キーとキャンセル関数をキーと値のペアとして Map オブジェクトに保存することができます。Map を使用する利点は、繰り返しのリクエストがあるかどうかをすばやく判断できることです。 'qs' から qs をインポートします const pendingRequest = 新しい Map(); // GET -> パラメータ; POST -> データ const requestKey = [メソッド、URL、qs.stringify(params)、qs.stringify(data)].join('&'); const cancelToken = new CancelToken(関数executor(cancel) { if(!pendingRequest.has(requestKey)){ 保留中のリクエストを設定します(リクエストキー、キャンセル)。 } }) 重複したリクエストが発生した場合、キャンセル関数を使用して、以前に発行されたリクエストをキャンセルできます。リクエストをキャンセルした後、キャンセルされたリクエストを pendingRequest から削除する必要もあります。リクエストをキャンセルする方法と重複したリクエストを検出する方法がわかったので、重複したリクエストをキャンセルする方法を見てみましょう。 3. 繰り返しリクエストをキャンセルする方法すべてのリクエストを処理する必要があるため、重複したリクエストをキャンセルする機能を実装するには、Axios のインターセプター メカニズムの使用を検討できます。 Axios は開発者にリクエスト インターセプターとレスポンス インターセプターを提供します。これらは次の機能を備えています。
3.1 補助機能の定義リクエスト インターセプターとレスポンス インターセプターを構成する前に、次の 3 つの補助関数を定義しましょう。 generateReqKey: 現在のリクエスト情報に基づいてリクエスト キーを生成するために使用されます。 関数generateReqKey(config) { const { メソッド、URL、パラメーター、データ } = config; [メソッド、URL、Qs.stringify(params)、Qs.stringify(data)].join("&"); を返します。 } addPendingRequest: 現在のリクエスト情報を pendingRequest オブジェクトに追加するために使用されます。 const pendingRequest = 新しい Map(); 関数 addPendingRequest(config) { リクエストキーを生成するには、config を使用します。 config.cancelToken = config.cancelToken || 新しい axios.CancelToken((キャンセル) => { 保留中のリクエストにリクエストキーがある場合 保留中のリクエストを設定します(リクエストキー、キャンセル)。 } }); } removePendingRequest: 重複したリクエストがあるかどうかを確認し、重複している場合は送信されたリクエストをキャンセルします。 関数removePendingRequest(config) { リクエストキーを生成するには、config を使用します。 保留中のリクエストにリクエストキーがある場合 リクエストキーをキャンセルします。 リクエストキーをキャンセルします。 保留中のリクエストを削除します(リクエストキー)。 } } generateReqKey、addPendingRequest、および removePendingRequest 関数を作成したら、リクエスト インターセプターとレスポンス インターセプターを設定できます。 3.2 リクエストインターセプターの設定axios.interceptors.request.use( 関数(設定){ removePendingRequest(config); // 重複したリクエストがあるかどうかを確認します。重複している場合は、送信したリクエストをキャンセルします。 addPendingRequest(config); // 現在のリクエスト情報を pendingRequest オブジェクトに追加します。 return config; }, (エラー) => { Promise.reject(error) を返します。 } ); 3.3 レスポンスインターセプターの設定axios.interceptors.response.use( (応答) => { removePendingRequest(response.config); //pendingRequest オブジェクトからリクエストを削除します。 return response; }, (エラー) => { removePendingRequest(error.config || {}); // pendingRequest オブジェクトからリクエストを削除します if (axios.isCancel(error)) { console.log("重複したリクエストをキャンセルしました: " + error.message); } それ以外 { // 例外処理を追加する } Promise.reject(error) を返します。 } ); 完全なサンプルコードはかなり長いため、具体的なコードは掲載しません。ご興味がございましたら、以下のアドレスにアクセスしてサンプルコードを閲覧することができます。 完全なサンプルコード: https://gist.github.com/semlinker/e426780664f0186db434882f1e27ac3a ここでは、Axios の重複リクエストのキャンセル例の結果を見てみましょう。 上図からわかるように、重複したリクエストが発生した場合、先に送信された未完了のリクエストはキャンセルされます。以下に、フローチャートを使用して重複リクエストをキャンセルするプロセスをまとめます。 最後に、上記の質問、つまり、CancelToken は内部でどのように機能するかに答えましょう。 4. キャンセルトークンの仕組み前の例では、CancelToken コンストラクターを呼び出して CancelToken オブジェクトを作成しました。 新しい axios.CancelToken((キャンセル) => { 保留中のリクエストにリクエストキーがある場合 保留中のリクエストを設定します(リクエストキー、キャンセル)。 } }) 次に、lib/cancel/CancelToken.js ファイルで定義されている CancelToken コンストラクターを分析します。 // lib/cancel/CancelToken.js 関数CancelToken(エグゼキュータ) { if (typeof executor !== 'function') { throw new TypeError('executor は関数である必要があります。'); } var 解決Promise; this.promise = 新しいPromise(関数promiseExecutor(resolve) { 解決の約束 = 解決します; }); var トークン = this; executor(function cancel(message) { // キャンセルオブジェクトを設定する if (token.reason) { return; // キャンセルはすでにリクエストされています } token.reason = 新しいCancel(メッセージ); トークンを解決します。 }); } 上記のコードから、cancel オブジェクトは関数であることがわかります。この関数を呼び出すと、Cancel オブジェクトが作成され、resolvePromise メソッドが呼び出されます。このメソッドが実行されると、CancelToken オブジェクトの promise プロパティによって指される promise オブジェクトの状態が解決されます。それで、これを行う目的は何でしょうか?ここで、lib/adapters/xhr.js ファイルから答えを見つけました。 // lib/アダプタ/xhr.js if (config.cancelToken) { config.cancelToken.promise.then(関数onCanceled(キャンセル) { if (!リクエスト) { return; } request.abort(); // リクエストをキャンセルするreject(cancel); リクエスト = null; }); } 上記の内容を読んだ後、CancelToken の動作原理を理解できない友人もいるかもしれません。そこで、Abao 兄弟は、CancelToken の動作原理をみんなに理解してもらうために、別の図を描きました。 V. 結論この記事では、Axios で繰り返しリクエストをキャンセルする方法と、CancelToken の仕組みについて説明します。 以降の記事では、Abao Ge が Axios でデータ キャッシュを設定する方法を紹介します。 興味のある方は、ぜひお見逃しなく。 Axios での HTTP インターセプターと HTTP アダプターの設計と実装について学習したい場合は、「77.9K Axios プロジェクトから学ぶ価値のあることは何ですか」という記事をお読みください。 Axios による重複リクエストのキャンセルに関するこの記事はこれで終わりです。Axios による重複リクエストのキャンセルに関する詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。 6. 参考資料
以下もご興味があるかもしれません:
|
<<: Win10 に Linux ubuntu-18.04 デュアル システムをインストールする (インストール ガイド)
>>: OracleデータをMySQLデータベースに抽出する実装プロセス
ルート ルーティング コンポーネント (アプリの下のルート ルーティング コンポーネント。子コンポー...
イベント委任を使用してメッセージ ボード機能を実装します。 <!DOCTYPE html>...
目次1. インストール前の準備、インストールパッケージのダウンロード1 インストールの準備2 インス...
序文システム領域の使用量が大きすぎて消去する必要がある場合、または特定のファイルを消去する必要がある...
1. モバイル端末がリストスライドを処理するとき、WeChat には下部にページに戻るボタンが組み...
目次序文1. プロジェクトアーキテクチャ2. Echart公式サイトにアクセスして自己分析を学ぶ2....
Linux システム管理者にとって、サービスがポートに正しくバインドされているか、またはポートをリッ...
この記事では、簡単なショッピングフォームを実装するためのJavaScriptの具体的なコードを参考ま...
目次原理ネットワーク環境の準備インストール前の準備NIS サーバー操作NIS クライアント操作原理N...
コードはさらに合理化できますが、時間の制約があるため、まずはここで投稿して、自分で最適化してメニュー...
以下のように表示されます。主に認証コマンドを実行します: 2つの方法1. 任意のホストがユーザー b...
目次1. nginxプロセスロックの役割2. エントリーレベルのロックの使用3. nginxプロセス...
序文ご存知のとおり、ブラウザの相同性戦略とクロスドメイン方式も、フロントエンド面接で頻繁に遭遇する問...
JSON データを美しいインデント形式で表示するには、最も単純な JSON.stringify 関...
2つの小さな問題ですが、長い間私を悩ませていました。最初の質問テキストエリアの左側のテキストは常にテ...