序文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データベースに抽出する実装プロセス
前回の記事では、Docker を使用して Laravel アプリケーションをデプロイする方法について...
商用データベースの場合、データベースのアップグレードは優先度が高く、バージョンアップのロードマップ、...
序文echarts は私が最もよく使用するチャート作成ツールであり、非常に完全なエコシステムとコンテ...
mysqladmin ツールの使用形式は次のとおりです。 mysqladmin [オプション] コ...
目次導入効果原理形状練習するこの記事では、例を使用して、MySQL マスター/スレーブ レプリケーシ...
mysql-5.7.17 のインストールについては記事の下部で紹介されているので、参考にしてください...
1. 問題の紹介ユーザー テーブルに 3 つのフィールドが含まれているシナリオを想定します。 id、...
この記事では、vue3.0の手動カプセル化ページングコンポーネントの具体的なコードを参考までに紹介し...
XHTML CSS ページ制作中に遭遇する問題の解決策は、解決策と呼ぶには少々大げさです。せいぜい、...
yum install httpd php mariadb-server –yランプの動作環境を設定...
marquee タグを使用してフォントのスクロールを設定したいです。コードは次のように記述しましたが...
1.MySQLのバージョン [root@clq システム]# mysql -v MySQL モニター...
序文データ型変換とは何ですか?フォームまたはプロンプトを使用して取得されるデフォルトのデータ型は文字...
[LeetCode] 185. 部門別給与上位3位従業員テーブルにはすべての従業員が保持されます。...