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文の実行プロセスの詳細な説明

推薦する

MySQL Limitクエリのパフォーマンスを向上させる方法

MySQL データベース操作では、一部のクエリを実行するときにデータベース エンジンが完全なテーブル...

MySQLでテーブルを作成し、フィールドコメントを追加する方法

コードと例を直接投稿する #テーブル作成時にコメントを記述する CREATE TABLE useri...

MySQL 完全折りたたみクエリ正規マッチングの詳細な説明

概要前の章では、クエリのフィルター条件について学習しました。MySQL では、like % ワイルド...

MySQL インデックス プッシュダウンの詳細

目次1. 左端接頭辞原則2. 表に戻る3. インデックスプッシュダウン序文:インデックス プッシュダ...

Vue+elementを使用してページ上部のタグを実装する方法の詳細な説明

目次1. ページレンダリング2. タグを切り替える3. タグを削除するこのようなタグはどのように記述...

アップロード画像コントロールを実現するネイティブ js

この記事の例では、アップロード画像コントロールを実装するためのjsの具体的なコードを参考までに共有し...

Linuxでスクリーンショットを撮って編集するための最高のツール

メインのオペレーティング システムを Windows から Ubuntu に切り替えたとき、最初に考...

HTML フォームタグチュートリアル (2):

このチュートリアルでは、ウェブデザインにおけるFORMフォームタグのさまざまな属性の応用を紹介します...

Linux で Grafana をインストールし、InfluxDB モニタリングを追加する方法

Grafana をインストールします。公式 Web サイトでは、直接インストールできる Ubuntu...

SSL で Nginx リバース プロキシを構成する簡単な手順

序文リバース プロキシは、Web 経由で行われたリクエスト (http と https の両方) を...

Linux で固定 IP を設定する方法 (テスト済みで効果的)

まず、仮想マシンを開きます xshell5 を開いて仮想マシンに接続します (より便利です。Linu...

ネイティブWeChatアプレット開発におけるreduxの使用の詳細な説明

前提複雑なシナリオでは、複数の異なるページ間で大量のデータを使用したり変更したりする必要があります。...

JavaScript の高度なクロージャの説明

目次1. 閉鎖の概念追加の知識ポイント: 2. 閉鎖の役割: 3. 閉鎖例3.1 liをクリックする...

MySQLのネストされたトランザクションで発生する問題

MySQL はネストされたトランザクションをサポートしていますが、それを実行する人は多くありません....

linuxdeployqt を使用して Ubuntu で Qt プログラムをパッケージ化する問題を解決する

いくつかの Qt インターフェース プログラムを作成しましたが、Qt 環境がインストールされていない...