問題の説明: 非同期リクエストの数が不確定な場合、数百の http リクエストが瞬時に発生したときに無数のコール スタックが蓄積され、メモリ オーバーフローの問題が発生するのを防ぐためです。 要件: 同時リクエストの数を一度に 3 未満に制限し、応答結果をできるだけ早く取得します。 同じ面接の質問: 次の要件を満たすバッチ リクエスト関数 multiRequest(urls, maxNum) を実装します。
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 をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Django+mysql の設定と簡単な操作データベースのサンプルコード
XML スキーマは、DTD に代わる XML ベースのものです。 XML スキーマは、DTD に代わ...
目次序文いくつかの一般的なビット操作ビットAND (&)ビットOR (|)ビット否定(~)マ...
Dockerfile内の指定されたファイルに複数の行を追加します。echoの後の「$」記号に注意し...
JSON (JavaScript Object Notation、JS Object Notatio...
目次導入Homebrewをインストールするnvmをインストールするノードをインストールするインストー...
この記事では、MySQL のデータベース テーブルの容量を確認するためのコマンド ステートメントを紹...
この記事では、例を使用して、MySQL クエリ ステートメントの簡単な操作を説明します。ご参考までに...
123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...
この記事では、優れた Web ページのカラー マッチングの事例を 20 件集めて紹介します。これらの...
サーバーサイドレンダリング (SSR) を使用する理由検索エンジンのクローラーが完全にレンダリングさ...
apt-get を使用してインストールすると、非常に遅くなります。国内のソースを変更すると、この問題...
この記事では、ローカル マシンに Java 8 をインストールせずに、Java 8 を使用して簡単な...
GROUP BY 句と HAVING 句を紹介する前に、まず SQL 言語の特殊な関数である集計関数...
目次1. マップされた型2. マッピング修飾子3. キーの再マッピング4. さらなる探究序文: Ty...
数学、物理学、および一部の科学技術分野で使用される特殊記号は多数あります。Unicode コードには...