問題の説明: 非同期リクエストの数が不確定な場合、数百の 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 の設定と簡単な操作データベースのサンプルコード
HTML画像にハイパーリンクを追加すると醜い青い枠線が表示される次のように:解決: CSS スタイル...
方法1: コマンドラインの変更次の図に示すように、MySQL コンソールを開いて「set GLOBA...
序文以前、rem適応についての記事を書きましたが、具体的なパッケージは紹介しませんでした。今日は、よ...
<br />前回の記事:Webデザイン講座(4):素材と表現について Webデザイン上級...
目次序文一般的な方法1. 親コンポーネントを介して子コンポーネントの発行イベントをリッスンしてpro...
トリガー:トリガーの使用シナリオと対応するバージョン:トリガーは次の MySQL バージョンで使用で...
目次Tomcat でプロジェクトを展開する 3 つの方法プロジェクトをwebappsディレクトリに直...
目次1. 基本概念の紹介2. ネットワークIOの読み取りと書き込みのプロセス3. 5つのLinuxネ...
1. ビジネスシナリオ最近はファイルのアップロードやダウンロードに関する開発をしています。ダウンロー...
コンセプト紹介: 1. px (ピクセル):仮想的な長さの単位で、コンピュータ システムのデジタル画...
序文Javaプログラミングでは、ほとんどのアプリケーションはMavenに基づいて構築されており、配信...
問題の説明: docker run -p 19918:19918/tcp -v /etc/local...
最近、モバイル ページを開発しているときに、ページの幅が 100% の場合、高さは幅の半分になり、携...
今日のタスク1. Linuxディストリビューションの選択2.vmwareが仮想マシン(centos)...
これまでのプロジェクトはすべて Windows システム環境にデプロイされていました。今回は Lin...