問題の説明: 非同期リクエストの数が不確定な場合、数百の 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 の設定と簡単な操作データベースのサンプルコード
序文JavaScript は習得が最も簡単な言語の 1 つであるため、成長と繁栄を続けており、市場に...
選択ドロップダウン リスト フォームは誰もがよく知っているかもしれませんが、デフォルトのドロップダウ...
1. HTMLの概要1.HTML: ハイパーテキスト マークアップ言語。これはプログラミング言語では...
序文: 「MySQL 入門」シリーズの記事は終了しました。今後も引き続き MySQL に焦点を当て、...
「Enter != Submit」問題を実装するには、通常、「ボタンの種類」と「入力ボックスの数」か...
著者が MySQL を使用してユーザーを追加していたところ、ユーザー名が間違って記述されていることに...
ハートの属性不透明度: .999 は要素のスタッキングコンテキストを作成し、ボタン6と8のアニメーシ...
序文この記事では、Windows で Mysql をバックアップするための簡単な BAT スクリプト...
WeChat ミニプログラム コンポーネント設計仕様コンポーネントベースの開発という考え方は、私の開...
CSS の優先順位について話す前に、CSS とは何か、CSS が何に使用されるのかを理解する必要があ...
序文この記事では、MySQL 8.0 の新機能を使用して再帰クエリを実装します。詳細なサンプル コー...
前面に書かれた最近、Mycat で特別なトピックを書いています。最近、多くの友人が面接に出かけている...
セルでは、明るい境界線の色を個別に定義できます。 > 基本構文<TD ボーダーカラーライ...
脆弱性の紹介SigRed の脆弱性はワーム化可能であるため非常に危険です。つまり、ユーザーの介入なし...
目次新しいユーザーを作成する新規ユーザーを承認する新規ユーザーのSSHキーログインを有効にする他のS...