リクエスト数を制限するために Ajax 同時リクエストを実装するために js を使用するサンプル コード

リクエスト数を制限するために Ajax 同時リクエストを実装するために js を使用するサンプル コード

問題の説明: 非同期リクエストの数が不確定な場合、数百の http リクエストが瞬時に発生したときに無数のコール スタックが蓄積され、メモリ オーバーフローの問題が発生するのを防ぐためです。

要件: 同時リクエストの数を一度に 3 未満に制限し、応答結果をできるだけ早く取得します。

同じ面接の質問:

次の要件を満たすバッチ リクエスト関数 multiRequest(urls, maxNum) を実装します。

  • 同時接続の最大数maxNumが必要です
  • リクエストが返されるたびに、新しいリクエストを追加するためのスロットが開いたままになります。
  • すべてのリクエストが完了すると、結果が URL の順に出力されます。

1. Promise.all に基づくシリアルおよび並列 Ajax の実装

通常、非同期リクエストは Promise に基づいてカプセル化されます。

シリアル: 1つの非同期リクエストが完了すると、次のリクエストが行われます

並列処理: 複数の非同期リクエストが同時に処理される

例: シリアル

var p = 関数() {
 新しいPromise(function(resolve,reject))を返す{
  タイムアウトを設定する(() => {
   コンソールログ('1000')
   解決する()
  }, 1000)
 })
}
var p1 = 関数() {
 新しいPromise(function(resolve,reject))を返す{
  タイムアウトを設定する(() => {
   コンソールログ('2000')
   解決する()
  }, 2000)
 })
}
var p2 = 関数() {
 新しいPromise(function(resolve,reject))を返す{
  タイムアウトを設定する(() => {
   コンソールログ('3000')
   解決する()
  }, 3000)
 })
}


p().then(() => {
 p1() を返す
}).then(() => {
 p2() を返す
}).then(() => {
 コンソールログ('終了')
})

平行:

var promises = 関数 () {
 [1000, 2000, 3000].map(current => { を返します。
  新しいPromise(function(resolve,reject))を返す{
   タイムアウトを設定する(() => {
    console.log(現在)
   }、 現在)
  })
 })
}

Promise.all(promises()).then(() => {
 コンソールログ('終了')
})

Promise.all(promises: []).then(fun: function);

promise.allは、thenコールバックを実行する前に、配列内のすべてのpromiseオブジェクトが解決された状態に到達することを保証します。

Promise.all 同時実行制限

意味: 各時点で同時に実行される Promise の数は固定されており、最終的な実行結果は元の Promise.all と一致したままになることを意味します。

アイデアと実装

これは、再帰呼び出しとリクエストの最大数の設定を使用して実装されます。そして、これらのリクエストはそれぞれ完了すると再帰的に送信され続け、urls内の特定のURLは渡されたインデックスによって決定され、最終的な出力順序が混乱せず、順番に出力されるようにします。

コード実装:

関数 multiRequest(urls = [], maxNum) {
 //リクエストの合計数 const len ​​= urls.length;
 // リクエスト数に基づいてリクエスト結果を保存する配列を作成します。const result = new Array(len).fill(false);
 // 現在完了した数 let count = 0;

 新しい Promise を返します ((resolve, reject) => {
  // maxNum をリクエストします while (count < maxNum) {
   次();
  }
  関数 next() {
   現在の値を count++ とします。
   // 境界条件を処理する if (current >= len) {
    // すべてのリクエストが完了したら、Promise を成功状態に設定し、結果を Promise 値として返します。result.includes(false) && resolve(result);
    戻る;
   }
   const url = urls[現在の];
   console.log(`start ${current}`、新しいDate().toLocaleString());
   フェッチ(url)
    .then((res) => {
     // リクエスト結果を保存します。 result[current] = res;
     console.log(`Completed${current}`, 新しい Date().toLocaleString());
     // リクエストが完了していない場合は、if (current < len) {を再帰します。
      次();
     }
    })
    .catch((エラー) => {
     console.log(`${current}` の終了、新しい Date().toLocaleString());
     結果[現在] = err;
     // リクエストが完了していない場合は、if (current < len) {を再帰します。
      次();
     }
    });
  }
 });
}

コード実装:

  // タスクリスト->新しいタスク uploadFile() {
   _this = this とします。
   var アップロードスレッド制限数 = 3,
    アップロードスレッド数 = 0、
    送信完了数 = 0、
    結果終了数 = 0;
   var マーク = 0;
   var タスク = [];
   var アップロード = 関数 () {
    (アップロードスレッド数 < アップロードスレッド制限数){
     (sendFinishNum >= _this.fileList.length)の場合{
      結果完了数 >= _this.fileList.length の場合 {
       creatTask(); // リクエストを完了する}
      戻る;
     }
     (関数(j) {
      item = _this.fileList[j]とします。
      p = new FormData();
      p.append("ファイル", 項目);
      タスク.push(
       アクシオス({
        メソッド: "post",
        url: `${window.UL_CONFIG.BASEURL}/api/files/upload`,
        データ: p,
        onUploadProgress: (progressEvent) => {
         (let i in _this.rowData) {
          _this.rowData[i].name === アイテム.name
           ? (_this.rowData[i].percent = Math.round(
             (progressEvent.loaded / progressEvent.total) * 100
            ))
           : "";
         }
        },
       })
        .then((res) => {
        /* obj = {} とします。
         obj.url = `${window.UL_CONFIG.BASEURL}/api/files/${res.data}`;
         obj.fileName = アイテム名;
         obj.fmt = _this.ruleForm.format;
         obj.samplingRate = _this.ruleForm.samplingRate;
         fileUrls.push(obj); */
        })
        .catch((e) => {
           ? (_this.rowData[i].パーセント = 0)
         _this.$notify.error({
          タイトル: 「エラー」、
          メッセージ:「サービス接続エラー」+ item.name +「アップロードに失敗しました」
         });
        .finally(() => {
         アップロードスレッド数--;
         結果終了数++;
         アップロード();
      );
     })(送信完了番号);
     アップロードスレッド数++;
     送信完了番号++;
    }
   };
   var createTask = 関数 () {
    axios.all(タスク).then((res) => {
     //新しいアップロードタスクを作成する/* let fd1, fd2, calcFlag, flagArr, language;
     fd1 = {};
     flagArr = Object.assign([], _this.ruleForm.checkList);
     if (_this.ruleForm.recognize == "自動認識") {
      flagArr.push("2");
     calcFlag = flagArr.reduce(
      (accu, curr) => 数値(accu) + 数値(curr)
     );
     _this.ruleForm.recognize == "自動的に認識する"
      ? (言語 = "")
      : (言語 = _this.ruleForm.recognize);
     fd1.processContent = calcFlag;
     fd1.remark = _this.ruleForm.remark;
     fd1.name = _this.ruleForm.taskName;
     fd1.fmt = _this.ruleForm.format;
     fd1.サンプリングレート = _this.ruleForm.サンプリングレート;
     fd1.language = 言語;
     fd1.type = 1; // タイプ: 1 オーディオ、2 ビデオ fd1.files = fileUrls; */
     newTask(fd1).then((res) => {
      /* _this.cmpltBtnState = false;
      _this.$store.commit("setTaskId", res.data.id);
      _this.submitFailNumber = res.data.submitFailNumber; */
      _this.$parent.dataInit();
     });
    });
   アップロード();
  },

これで、js を使用して同時 Ajax リクエストの数を制限するサンプル コードを実装するこの記事は終了です。js Ajax 同時リクエスト制限の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • js は axios 制限リクエスト キューを実装します
  • JavaScript で Promise を使用して同時リクエスト数を制御する方法
  • gin 投稿リクエストのJSON本文を取得する
  • JSはリクエストディスパッチャーを実装する
  • PHPはChromeフォームのリクエストデータをインターフェースで使用されるJSONデータに変換する機能を実装します。
  • JavaScript 中断要求に対するいくつかの解決策の詳細な説明

<<:  Django+mysql の設定と簡単な操作データベースのサンプルコード

>>:  GNU Parallelの具体的な使用法

推薦する

Centos8 (最小インストール) Python3.8+pip のインストール方法に関するチュートリアル

Python8のインストールを最小化した後、Python3.8.1をインストールしました。オンライン...

変数が空かどうかを判定するシェルの方法の概要

シェルで変数が空かどうかを判断する方法シェルプログラミングでは、パラメータのエラーチェック項目に、変...

Centos7 への MySQL8 のインストールチュートリアル

MySQL 8 の新機能: MySQL をバージョン 5.x から 8.x に直接アップグレードする...

データベース復旧エラーの原因となる MySQL 文字セットの簡単な分析

MySQL の文字セットエンコーディングが正しくないデータをインポートすると、エラーが表示されます。...

HTMLハイパーリンクタグAのTARGET属性の詳細な説明

ハイパーリンク <a> タグはリンク ポイントを表します。これは英語の単語「anchor...

CSSを使用して、頻繁に表示される奇妙なボタンを簡単に実装します。

背景グループでは、CSS を使用してインセット コーナー ボタンを実装する方法や、矢印付きのボタンを...

HTML ページ ヘッダー コード例の詳細な説明

知識ポイント1: ヘッダー情報にWebページのベースURLを設定するベース URL の本質は、ハイパ...

HTML に FLASH へのリンクを追加し、すべての主要ブラウザと互換性を持たせる方法

まずコードを見てみましょうコードをコピーコードは次のとおりです。 <div style=&qu...

NavicatがMySQLに接続すると、10060、1045エラーとmy.iniの場所が報告されます。

Navicat は、データベースに接続するときにエラー 10060 および 1045 を報告します...

VueでEchartsチャートの幅と高さの適応を実現する実践

目次1. インストールとインポート2. 手ぶれ補正機能を定義する3. チャートコードを描くinit ...

クリエイティブな会社概要ウェブページデザイン

ユニークな「About」ページ自分を他の人たちと差別化する素晴らしい方法は、本当にユニークな自己紹介...

データベースSQL文の最適化

最適化する理由:実際のプロジェクトが開始され、データベースが一定期間稼働した後、初期のデータベース設...

Nginx ロードバランシング/SSL 構成の実装

負荷分散とは何ですか?ドメイン名が複数の Web サーバーを指している場合は、nginx ロード バ...

DockerはホストのMysql操作に接続します

今日、会社のプロジェクトでは docker を設定する必要があります。Windows に正常にインス...

Windows Server 2019 IIS10.0+PHP(FastCGI)+MySQL 環境構築チュートリアル

準備1. 環境の説明:オペレーティング システム: Windows Server 2019 PHP ...