JavaScript が重複したネットワークリクエストを防ぐ方法の例

JavaScript が重複したネットワークリクエストを防ぐ方法の例

序文

開発中は、インターフェース要求の繰り返しによってさまざまな問題が発生することがよくあります。
ネットワーク リクエストが繰り返されると、ページが複数回更新され、ページのジッターが発生し、ユーザー エクスペリエンスに影響します。
たとえば、現在のページ要求がまだ応答しておらず、他のルートに切り替えられた場合、応答が返されるまでこれらの要求は終了されません。
ユーザー エクスペリエンスの観点から見ても、ビジネスの厳密さの観点から見ても、無駄なリクエストをキャンセルすることは避けるべきことです。

実装のアイデア

** 1. リクエストを送信する前に、現在のリクエスト アドレス (URL + メソッド + パラメータ) をインターセプトします。
** 2. 現在のアドレスを保存するためにリクエストキューを開きます。
** 3. 各リクエストのリクエスト キューに現在の URL アドレスがあるかどうかを確認します。
** 4. 現在の URL アドレスがリクエスト キュー内にある場合は、現在のリクエストをキャンセルします。
** 5. そうでない場合は、リクエストを送信します。リクエスト データが返されたら、リクエスト キュー内の現在の URL アドレスをクリアします。

1. 通常、インターフェースは次のように記述します。

リクエストインターフェースファイル

import { http } from '@/plugin/axios'; // リクエストインターフェース http をインポートします

// 初期化エクスポート関数 getInit(params) {
  http({を返す
    メソッド: 'get'、
    URL: '/xxx/xxx/xx',
    パラメータ、
  });
}

主なことは、ここで http メソッドを実行するときに操作を実行することです。
http 関数を実行すると、リクエストのすべての構成が取得され、promise オブジェクトが返されます。

2. ここではaxiosの使い方を説明します。リクエスト関数を実行するときに外側にレイヤーをラップするという考え方です。

axios.js 構成ファイル

'axios' から axios をインポートします。
import { httpRequest, completeRequest } from './options'; // 実装したいロジックファイルはこちらです // ここでリクエストインターセプションをいくつか行い、具体的なレスポンスインターセプション操作については axios ドキュメントを参照してください const service = axios.create({
  ベースURL: 'xxx/xxx',
});

// リクエストインターセプター service.interceptors.request.use(config => {}, error => {})

// レスポンスインターセプター service.interceptors.response.use(response => {
 completeRequest(response); // 2. レスポンスリクエストが実行のために返される}, error => {
 
})

export function http(config) { // => ここで config は渡されるリクエスト構成パラメータです return httpRequest(config, service); // + 1. ここでいくつかの論理演算を実行します}

3. ネットワーク設定ファイルの重複を防ぐ

オプション.js
(1)リクエストを送信する前に、リクエストキューに現在のリクエストがあるかどうかを確認します(URLアドレスによって決定されます)

  • リクエストキューには現在のURLアドレスがあり、リクエストをキャンセルしてpromise.reject failureを返します。
  • 現在リクエストがないので、リクエストは通常​​どおり送信されます。
/**
 * 責任: 重複したネットワークリクエストを防ぐ*
 */

let list = new Set(); // 1. リクエストキュー // MergeメソッドパラメータURLアドレス function getUrl(config = {}) {
 // リクエストパラメータの取得、パラメータ、ポストリクエストデータパラメータ、baseURL
 const { url, method, params, data, baseURL = '' } = config;
 urlVal = url.replace(baseURL, '');
 `${urlVal}?${method === 'get' ? getformatObjVal(params) : getformatObjVal(data)}` を返します。
}

// URLアドレスの処理 const getformatObjVal = (obj) => {
 obj = typeof obj === 'string' ? JSON.parse(`${obj}`): obj;
 var str = [];
 (pをobjに入れる) {
  obj.hasOwnProperty(p) && p !== '_t' の場合 {
   var item = obj[p] === null ? '' : obj[p]; // nullを処理する
   str.push(encodeURIComponent(p) + '=' + encodeURIComponent(item));
  }
 }
 str.join('&') を返します。
}

// 2. リクエストメソッドのエクスポート function httpRequest(config = {}, axios) {
 const url = getUrl(config); //3. ここで URL アドレスを取得しますif (list.has(url)) { // 4. リクエスト キューに現在の URL アドレスがあるかどうかを確認しますreturn Promise.reject('In the request'); // 5. リクエスト キュー内の現在のリクエストをキャンセルし、Promise の失敗結果を返します}
 
 // 6. リクエスト キューには現在の URL アドレスがありません。リクエストを送信し、URL アドレスをリクエスト キューに格納します。list.add(url);
 Promise.resolve(axios) を返します。 
}

(2)リクエスト応答が返ってきたら、リクエストキュー内の現在のURLアドレスを削除します(次のリクエストは正常に送信できます)。
オプション.js

// リクエストレスポンスが返ってきたらこの関数を実行します export function completeRequest(response = {}) {
 const { config } = response; // 1. レスポンス内のconfigは設定パラメータを取得できます const url = getUrl(config); // 2. URLアドレスを取得します if (list.has(url)) {
  list.delete(url); // 3. リクエストキュー内の現在のリクエスト URL アドレスを削除します}
}

アクシオス

'axios' から axios をインポートします。
import { httpRequest, completeRequest } from './options'; // 重複リクエストを防ぐ const service = axios.create({
  ベースURL: 'xxx/xxx',
});

// リクエストインターセプター service.interceptors.request.use(config => {}, error => {})

// レスポンスインターセプター service.interceptors.response.use(response => {
 completeRequest(response); // 2. レスポンスリクエストが戻ってきて実行します +
}, エラー => {
 
})


// エクスポート要求エクスポート関数 http(config) {
  return httpRequest(config, service); // 1. リクエストを送信する前に実行する}

この時点で、重複したネットワーク リクエストの防止は実現できましたが、まだ問題が残っています。応答リクエストで例外が発生した場合、リクエスト キュー内の現在の URL アドレスをクリアする必要があります。クリーンアップされない場合、次のリクエストは直接キャンセルされます (ここではすべてのリクエスト キューをクリアするメソッドを記述しましたが、独自のシナリオに従って記述できます)。

/**
 * すべてのリクエストキューをクリアします */
エクスポート関数clearRequestList() {
 list = new Set(); // ここでクリアするだけです }

完全な http.js ファイル

'axios' から axios をインポートします。
import { httpRequest, completeRequest, clearRequestList } from './options'; // 重複したリクエストを防ぐ +

constサービス = axios.create({
  ベースURL: 'xxx/xxx',
});

// リクエストインターセプター service.interceptors.request.use(config => {}, error => {})

// レスポンスインターセプター service.interceptors.response.use(response => {
 completeRequest(response); // 2. レスポンスリクエストが実行のために返される}, error => {
 クリアリクエストリスト(); // + 
})


// エクスポート要求エクスポート関数 http(config) {
  return httpRequest(config, service); // 1. リクエストを送信する前に実行する}

完全なoptions.js

/**
 * 責任: 重複したネットワークリクエストを防ぐ*
 */

let list = new Set(); // 1. リクエストキュー // MergeメソッドパラメータURLアドレス function getUrl(config = {}) {
 // リクエストパラメータの取得、パラメータ、ポストリクエストデータパラメータ、baseURL
 const { url, method, params, baseURL = '' } = config;
 urlVal = url.replace(baseURL, '');
 `${urlVal}?${method === 'get' ? getformatObjVal(params) : 'post'}` を返します。
}

// URLアドレスの処理 const getformatObjVal = (obj) => {
 obj = typeof obj === 'string' ? JSON.parse(`${obj}`): obj;
 var str = [];
 (pをobjに入れる) {
  obj.hasOwnProperty(p) && p !== '_t' の場合 {
   var item = obj[p] === null ? '' : obj[p]; // nullを処理する
   str.push(encodeURIComponent(p) + '=' + encodeURIComponent(item));
  }
 }
 str.join('&') を返します。
}

// 2. リクエストメソッドのエクスポート function httpRequest(config = {}, axios) {
 const url = getUrl(config); //3. ここで URL アドレスを取得しますif (list.has(url)) { // 4. リクエスト キューに現在の URL アドレスがあるかどうかを確認しますreturn Promise.reject('In the request'); // 5. リクエスト キュー内の現在のリクエストをキャンセルし、Promise の失敗結果を返します}

 // 6. リクエスト キューには現在の URL アドレスがありません。リクエストを送信し、URL アドレスをリクエスト キューに格納します。list.add(url);
 Promise.resolve(axios) を返します。
}


/**
 * この関数を実行するためのリクエスト応答 */
エクスポート関数 completeRequest(response = {}) {
 const { config } = response; // 1. レスポンス内の config は構成パラメータを取得できます const url = getUrl(config); // 2. URL アドレスを取得します list.has(url) && list.delete(url); // 3. リクエスト キュー内の現在のリクエスト URL アドレスを削除します }

/**
 * すべてのリクエストキューをクリアします */
エクスポート関数 clearRequestList(error) {
 // エラーは構成を取得し、いくつかの操作を実行できます。
 list = new Set(); // ここでクリアするだけです }

上記は、ネットワーク リクエストを防止する方法です。以前は、axios で CancelToken を使用してリクエストをキャンセルしていましたが、いくつか問題がありました。

  1. リクエスト ファイルの構成が必要であり、ユーザー フレンドリーではなく、チーム開発の構成にも面倒です。
  2. リクエストごとにCancelTokenを設定する必要があります。 使い方は2通りあります。詳細は公式サイトのドキュメントを参照してください。

これで、JavaScript で重複したネットワーク リクエストを防ぐ方法についての記事は終了です。JavaScript で重複したネットワーク リクエストを防ぐ方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JS Ajax リクエストの重複送信を防ぐ方法
  • JavaScriptはPromiseを使用して複数の繰り返しリクエストを処理します

<<:  Linux で特定の時間にコマンドを実行する方法

>>:  MySQLログシステムの詳細情報共有

推薦する

CSS でのフィルタープロパティの使用に関する詳細な説明

フィルター属性は要素の視覚効果を定義しますぼかし画像にガウスぼかしを適用します。 「半径」の値は、ガ...

Docker nginx + https サブドメイン設定の詳細なチュートリアル

今日はたまたま友人のサーバーの移転を手伝うことになり、サーバーの基本的な設備の設定を行ったのですが、...

アカウントとパスワードを記憶する機能を実現するVueの考え方とプロセス

目次実装のアイデアアカウント パスワードを保存する方法は 3 つあります。機能インターフェースアカウ...

JavaScript のクロージャの問題の詳細な説明

クロージャは、純粋関数型プログラミング言語の伝統的な機能の 1 つです。クロージャをコア言語構造の不...

MySQLは1つのテーブルからデータをクエリし、それを別のテーブルに挿入する実装方法

MySQLは1つのテーブルからデータをクエリし、それを別のテーブルに挿入する実装方法ウェブサイト開発...

MySQLで現在の時間間隔の前日のデータをクエリする

1. 背景実際のプロジェクトでは、分散スケジュールされたタスク実行の状況に遭遇することがあります。ス...

JavaScript オブジェクトからプリミティブ値への変換の詳細な説明

目次オブジェクトプロトタイプの値()オブジェクトプロトタイプtoString()シンボル.toPri...

vuex での Getter の使用法の詳細な説明

序文Vuex を使用すると、ストア内に「ゲッター」を定義できます (これはストアの計算されたプロパテ...

MySQL最適化ツール(推奨)

序文今日 GitHub を閲覧していたところ、SQL を最適化および書き換えるための sora とい...

Ubuntuサーバーの一般的なコマンドの概要

以下のコマンドのほとんどは、コンソール/ターミナル/シェルで入力する必要があります。 'su...

CentOS 6 は Docker を使用して Redis マスター スレーブ データベース操作例を展開します

この記事では、Docker を使用して Centos6 に Redis マスター/スレーブ データベ...

Layuiはログインインターフェース検証コードを実装します

この記事の例では、ログインインターフェース検証コードを実装するためのlayuiの具体的なコードを参考...

CSSプロパティに基づいたボタンホバーボーダーと背景アニメーションのコレクション

ハートの属性不透明度: .999 は要素のスタッキングコンテキストを作成し、ボタン6と8のアニメーシ...

スーパーバイザーによるDockerfileのマルチサービスイメージパッケージ操作

Dockerfileの作成yumソースを設定する cd /tmp/docker vim Docker...

DockerにRocketMQをインストールするための実装手順

目次1. 画像を取得する2. ブローカーサーバーを作成する3. ブローカーを作成する4. Rocke...