axios でリクエストをキャンセルし、重複リクエストを防ぐ方法について簡単に説明します。

axios でリクエストをキャンセルし、重複リクエストを防ぐ方法について簡単に説明します。

序文

実際のプロジェクトでは、リクエストに対して「手ぶれ防止」処理を実行する必要がある場合があります。これは主に、特定の状況下でユーザーが短時間にボタンを繰り返しクリックして、フロントエンドがバックエンドに複数のリクエストを繰り返し送信するのを防ぐためです。ここでは、よくある 2 つの実際的な状況を挙げます。

  • PC側 - 検索ボタンをダブルクリックすると、2つの検索要求がトリガーされる可能性があります
  • モバイル端末 - モバイル端末ではクリック遅延がないため、誤操作や多重操作が発生しやすく、リクエストの再送信が発生します。

読み込みマスクがある場合でも上記の状況が発生する可能性があるため、フロントエンドで重複したリクエストを防ぐ方法を検討する必要があります。

コア - キャンセルトークン

Axios でリクエストをキャンセルする中心的な方法は CanelToken です。公式ウェブサイトのドキュメントには、CancelTokenを使用する方法が2つ記載されています。ここでは、簡単な貼り付けとコメントの追加方法を紹介します。

方法1:

CancelToken は axios.CancelToken に置き換えられます。
const ソース = CancelToken.source();

axios.get('/user/12345', {
  //リクエストにはCancelTokenを設定する必要があります cancelToken: source.token
}).catch(関数(スロー) {
  // リクエストがキャンセルされた場合は、このメソッドに入り、(axios.isCancel(thrown)) かどうかを判断します。
    console.log('リクエストがキャンセルされました', throwed.message);
  } それ以外 {
    // エラーを処理する
  }
});

// 上記のリクエストをキャンセルします // source.cancel('messge') message はオプションであり、文字列である必要があります
source.cancel('ユーザーによって操作がキャンセルされました。');

方法2:

CancelToken は axios.CancelToken に置き換えられます。
キャンセルする;

axios.get('/user/12345', {
  // オプションで直接 cancelToken オブジェクトを作成します cancelToken: new CancelToken(function executor(c) {
    キャンセル = c;
  })
});

// 上記のリクエストをキャンセルします cancel();

実用的なアプリケーションとパッケージング

上記では axios のコアメソッドを例示しましたが、実際には公式ウェブサイトの例のようにこれらを使用することはほとんどありません。代わりに、axios インターセプターでグローバル構成管理を行います。この場合、上記のコードにいくつか変更を加える必要があります。

私が実装した一般的なアイデアは次のとおりです。

  • 進行中のすべてのリクエストをキャッシュする必要があります。リクエストを開始する前に、キャッシュ リスト内でリクエストが進行中かどうかを確認します。進行中の場合は、リクエストをキャンセルします。
  • リクエストが完了したら、リクエストを再送信できるようにキャッシュリストからリクエストを削除する必要があります。

アイデアが完成したら、すぐにコードに取り掛かりましょう

// 進行中のリクエストのリスト let reqList = []

/**
 * 重複リクエストを防止* @param {array} reqList - リクエストキャッシュリスト* @param {string} url - 現在のリクエストアドレス* @param {function} cancel - リクエスト中断関数* @param {string} errorMessage - リクエストが中断されたときに表示されるエラーメッセージ*/
const stopRepeatRequest = 関数 (reqList、url、cancel、errorMessage) {
  const errorMsg = エラーメッセージ || ''
  (i = 0 とします; i < reqList.length; i++) {
    if (reqList[i] === url) {
      キャンセル(エラーメッセージ)
      戻る
    }
  }
  reqList.push(url)
}

/**
 * リクエストの続行を許可する * @param {array} reqList すべてのリクエストのリスト * @param {string} url リクエストアドレス */
const allowRequest = 関数 (reqList, url) {
  (i = 0 とします; i < reqList.length; i++) {
    if (reqList[i] === url) {
      要求リスト.splice(i, 1)
      壊す
    }
  }
}

const サービス = axios.create()

// リクエストインターセプター service.interceptors.request.use(
  設定 => {
 キャンセルする
   // cancelToken オブジェクトを設定する config.cancelToken = new axios.CancelToken(function(c) {
     キャンセル = c
    })
    // 重複したリクエストを防ぎます。前のリクエストが完了していない場合、同じリクエストは停止されませんRepeatRequest(reqList, config.url, cancel, `${config.url} request is interrupted`)
    設定を返す
  },
  エラー => Promise.reject(エラー)
)

// レスポンスインターセプター service.interceptors.response.use(
  レスポンス => {
    // 遅延を増やします。同じリクエストが短期間に繰り返し送信されないようにする必要があります。setTimeout(() => {
      allowRequest(reqList、response.config.url) は、
    }, 1000)
    // ...リクエストが成功した後の後続の操作 // successHandler(response)
  },
  エラー => {
    もし(axios.isCancel(スロー)){
      console.log(スローされたメッセージ);
    } それ以外 {
      // 遅延を増やします。同じリクエストが短期間に繰り返し送信されないようにする必要があります。setTimeout(() => {
        allowRequest(reqList、error.config.url) は、
      }, 1000)
    }
    // ...リクエストが失敗した後の後続の操作 // errorHandler(error)
  }
)

いくつかの小さな詳細

上記の方法 2 のコードを使用して cancelToken を設定しなかったのはなぜですか?
axios のドキュメントには次のような注記があります:

注: 同じキャンセル トークンを使用して複数のリクエストをキャンセルできます。
同じトークンを使用して複数のリクエストをキャンセルできます。

したがって、各リクエストの前に新しいオブジェクトを作成したくありません。各キャンセルが正しく実行されるようにするには、必ず方法 2 を使用してください。前のメソッドでは、キャンセルが発生した後も後続のリクエストは引き続きキャンセルされます。

なぜ応答に遅延を追加する必要があるのでしょうか?
ユーザーが非常に短い期間内に同じリクエストを繰り返し行うことを望まないためです。
応答でリクエストをブロックすることと、リクエストでリクエストをブロックすることは、2 つの異なる概念であることに注意してください。
この要求は、前の要求が完了していない場合に同じ要求が再度開始されるのを防ぐためのものです。
この応答により、前のリクエストが完了してから一定期間内に同じリクエストが行われなくなります。

キャンセル時にメッセージだけでなくオブジェクトを渡すことはできますか?
公式インターフェースでは不可能です。公式ソースコードに従って再パッケージ化するか、サードパーティのプラグインを使用するか、別の方法(オブジェクトを JSON 文字列に変換し、必要に応じて再度変換する)を使用できます。

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

以下もご興味があるかもしれません:
  • Vue の Axios でリクエストをキャンセルし、重複リクエストを防ぐ方法

<<:  Zabbix で監視項目と集約されたグラフを設定するためのサンプルコード

>>:  mysql update文の実行プロセスの詳細な説明

推薦する

VMware 仮想マシンのインストール CentOS 8 (1905) システム チュートリアル ダイアグラム

世界的に有名な仮想マシン ソフトウェア VMware-workstation-full-15.5.0...

Docker を使用した ELK7.3.0 ログ収集サービスの導入に関するベスト プラクティス

最初に書くこの記事では、ELK 7.3.0 の展開についてのみ説明します。展開環境:システムセントO...

Linux環境でユーザーにsudo権限を追加する方法

sudo 設定ファイルsudo のデフォルトの設定ファイルは /etc/sudoers です。一般的...

mysqlタイムスタンプの使用

序文:タイムスタンプ フィールドは、MySQL でよく使用されます。たとえば、データ行が作成または変...

CentOS7 は Docker のバージョン 19 をデプロイします (簡単なので、従ってください)

1. 依存パッケージをインストールする [root@localhost ~]# yum insta...

スネークゲームを作るための Pygame コード

目次使用されるPygame関数スクリーンの作成ヘビの作成ヘビを動かすゲームオーバーの処理食事を増やす...

MySQL 8.0.13 のダウンロードとインストールのチュートリアル(画像とテキスト付き)

MySQL は最もよく使用されるデータベースです。詳しく知るには、コンピュータにインストールする必...

MySQLデータストレージプロセスパラメータの詳細な例

MySQL ストアド プロシージャ パラメータには、in、out、inout の 3 種類があります...

印刷広告を成功させるための「3I」基準

国内の多くの広告主にとって、印刷広告の制作と評価は、しばしばかなり主観的です。自分の感情や美的感覚に...

MySQLインデックスの詳細な分析

序文インデックスの選択はオプティマイザ段階の作業であることはわかっていますが、オプティマイザは万能で...

vue-router のハッシュモードと履歴モードの違い

vue-routerには2つのモードがありますハッシュモード履歴モード1. シングルページアプリケー...

Docker を使用して MySQL および Redis サービスをデプロイする方法

目次Dockerを使用してMySQLサービスをデプロイする方法DockerでRedisサービスをデプ...

JavaScriptの再帰の詳細

目次1. 再帰とは何ですか? 2. 再帰を使って数学の問題を解く1. 1 * 2 * 3 * 4 …...

JavaScript ベースの Web 計算機の実装

この記事では、ウェブ計算機のマインスイーパゲームを実装するためのJavaScriptの具体的なコード...

MySqlサブクエリINの実装と最適化

目次IN が遅いのはなぜですか? INとEXISTSのどちらが速いでしょうか?効率を向上させるにはど...