リクエスト数を制限するために 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の具体的な使用法

推薦する

HTML 画像 img にハイパーリンクを追加した後の醜い青い境界線の問題を解決する

HTML画像にハイパーリンクを追加すると醜い青い枠線が表示される次のように:解決: CSS スタイル...

MySQL で最大接続数を設定するためのヒントのまとめ

方法1: コマンドラインの変更次の図に示すように、MySQL コンソールを開いて「set GLOBA...

レム適応の一般的なパッケージ3つについて

序文以前、rem適応についての記事を書きましたが、具体的なパッケージは紹介しませんでした。今日は、よ...

Webデザインチュートリアル(5):Webビジュアルデザイン

<br />前回の記事:Webデザイン講座(4):素材と表現について Webデザイン上級...

子コンポーネントを通じて親コンポーネントのプロパティを変更するための Vue のさまざまな実装方法

目次序文一般的な方法1. 親コンポーネントを介して子コンポーネントの発行イベントをリッスンしてpro...

MySQL トリガーの使用シナリオとメソッドの例

トリガー:トリガーの使用シナリオと対応するバージョン:トリガーは次の MySQL バージョンで使用で...

tomcat デプロイメント プロジェクトの実装と IDEA との統合

目次Tomcat でプロジェクトを展開する 3 つの方法プロジェクトをwebappsディレクトリに直...

Linux の高性能ネットワーク IO と Reactor モデルの分析

目次1. 基本概念の紹介2. ネットワークIOの読み取りと書き込みのプロセス3. 5つのLinuxネ...

ファイルが存在するかどうかを判断する JavaScript サンプルコード

1. ビジネスシナリオ最近はファイルのアップロードやダウンロードに関する開発をしています。ダウンロー...

CSS における px、em、rem、pt の特徴、違い、変換について詳しく説明します。

コンセプト紹介: 1. px (ピクセル):仮想的な長さの単位で、コンピュータ システムのデジタル画...

Maven+Tomcat 基本イメージを構築する Docker の実装

序文Javaプログラミングでは、ほとんどのアプリケーションはMavenに基づいて構築されており、配信...

CSS を使用して等アスペクト比のアダプティブ コンテナを実装する方法

最近、モバイル ページを開発しているときに、ページの幅が 100% の場合、高さは幅の半分になり、携...

VMware および CentOS システムのインストール方法 - ルート パスワードをリセットする

今日のタスク1. Linuxディストリビューションの選択2.vmwareが仮想マシン(centos)...

CentOS で RPM を使用して MySQL 5.6 をインストールするチュートリアル

これまでのプロジェクトはすべて Windows システム環境にデプロイされていました。今回は Lin...