JS ベースの Ajax 同時リクエスト制御を実装する方法

JS ベースの Ajax 同時リクエスト制御を実装する方法

序文

最近、インタビューの質問を見ました。もちろん、この記事のタイトルである「Ajax 同時リクエスト制御」ですが、とても興味深いと思います。コミュニティで調べたところ、ByteDance からのインタビューの質問のはずです。多くの大物がこれを要約しています。私はそれらをすべて読んだので、自分で要約してみたいと思います。コードは記事の最後に掲載します。何か間違っている点があれば、指摘してください。

Ajax シリアルおよびパラレル

  • シリアル: 一般的に、次のインターフェースは、前のインターフェースから返されたデータを使用する必要があります。フロントエンドでよく使用されるリクエスト ライブラリは、Promise ベースの HTTP ライブラリである Axios です。これを実現するには、チェーン呼び出しまたは Async Await を直接使用できるため、ここでは説明しません。
  • 並列: 複数のリクエストが同時に発生します。一般的には、すべてのデータを取得した後にページをレンダリングしたり、その他の操作を実行したりするために使用されます。主にPromise.allに基づいています。実装方法は次のとおりです。

上記のシミュレーションはPromise.allに基づく並列操作を実装しており、出力結果は以下のとおりです。

これが終わりであり、存在しないと感じますか?さて、いよいよ本題です。ページが同時に何万ものリクエストを送信し、そのすべてが成功した後にいくつかの操作を実行する必要がある状況を想像してみましょう。結果はどうなるでしょうか?コードを実行できず、メモリがオーバーフローします。残念ながら、ここでこの記事のトピックに戻ります。同時 Ajax リクエストを制御するにはどうすればよいでしょうか?一度に一定数のリクエストだけを出力し、すべてが成功するまで続けるように依頼しました。次に、この操作を 2 つの方法で実装します。読者の皆さんのアドバイスをお待ちしています。

Ajaxの同時リクエスト制御のための2つのソリューション

Promiseベースの再帰

次の 2 つの方法は、どちらも上図の Tasks 配列を必要とします。覚えておいてください。Promise に基づく最初の方法は、次のような考え方です。同時実行プールを渡すと、ワークスペースのプールが作成されます。各ワークスペースは、実行する対応するタスク (リクエスト) を取得し、成功したら保存し、ワークスペースにタスクがなくなるまでタスク (リクエスト) を取得し続けます。もちろん、失敗した場合は直接終了します。これが一般的な考え方です。以下のコードの各行にコメントを付けました。どうぞご了承ください。

クラスベースの実装

2 番目の方法はクラスに基づいています。上記との違いは、この方法ではワークスペースが 1 つしか作成されないことです。基本的な考え方は、タスク (リクエスト) を実行するためのワークスペースを作成し、すべてのタスクをそこにプッシュしますが、毎回、対応する数の同時タスクしか実行できません。同時タスクの数より少ない場合は、タスク (リクエスト) がなくなるまでタスクを取得して実行し続けます。これで完了です。具体的な実装は次のとおりです。

コードショーケース

これら 2 つのメソッドの実装コードを以下に示します。

    const delay = 関数 delay(間隔) {
      新しい Promise((res,rej) => { を返す
        タイムアウトを設定する(() => {
          res(間隔)
        }, 間隔);
      })
    }


    タスクを = [() => {
      戻り遅延(1000)
    },() => {
      返品遅延(1003)
    },() => {
      返品遅延(1005)
    },() => {
      返品遅延(1002)
    },() => {
      返品遅延(1004)
    },() => {
      返品遅延(1006)
    }]

    // Promise.all を通じて並列処理を実装する Promise.all(tasks.map(task => task())).then(res => {
      コンソールログ(res);
    })

    // Promise に基づいて関数 creatRequest(tasks,pool) を実装します {
      // 毎回送信されるリクエストの数はプールによって制御されます
      プール = プール || 5
      // 各リクエストの結果を保存するために使用されます(順番に保存されます)
      結果 = [] とします。
      // together はワークスペースを作成するために使用されます。pool が渡されると、それに応じて複数のワークスペースが作成されます。// つまり、pool の長さと null の値を持つ配列を作成します。together = new Array(pool).fill(null),
      // インデックスは毎回取得されるタスク値です。index = 0;
      一緒に = 一緒に.map(() => {
        // Promise に基づく管理 return new Promise((resolve,reject) => {
          // 関数を作成し、すぐに実行する const run = function run() {
            // タスクプールが空の場合、リクエストが正常に送信されたことを意味します if(index >=tasks.length) {
              解決する()
              戻る 
            }
            // まず、現在の成功したリクエストの結果を保存するためのインデックスを保存します。let old_index = index,
            // 現在送信されているリクエストを取得し、インデックスを累積します。そのため、インデックスは上記に保存されます。 // ここでは、index++ が最初に計算されてから累積されますが、++index はその逆で、最初に累積されてから計算されます。task = tasks[index++];
            // リクエストを実行する task().then(result => {
            // 成功した結果を保存する results[old_index] = result
            // 再帰的に実行を続行します。つまり、タスクをワークスペースに取得して実行を続行します run();
            }).catch(理由 => {
              拒否(理由)
            })
          }
          // すぐにrun()を実行する
        })
      })
      // Promise.all を使用してワークスペースを制御します。つまり、一度に 2 つのリクエストを同時に実行します。 return Promise.all(together).then(() => results)
    }


    createRequest(タスク,2).then(結果 => {
      // 全体が成功するにはすべてが成功する必要があるので、結果を順番に保存します。console.log('success',results);
    }).catch(解決 => {
      // いずれか 1 つでも失敗すると、システム全体が失敗します console.log('failed');
    })



    // クラスに基づいて関数 creatRequest(tasks,pool,callback) を実装します {
      // パラメータの制限と検証 if(typeof pool === 'function') {
        コールバック = プール;
        プール = 5
      }
      if (typeof pool !== 'number') プール = 5
      if (typeof callback !== 'function') callback = function () {}
      //------
      クラスタスクキュー {
        // 実行回数 = 0;
        // すべてのタスクをキューに入れる queue = [];
        // タスク(リクエスト)の実行結果を保存します。 results = [];
        タスクをプッシュします。
          自分 = これ
          // タスクをワークスペースにプッシュします。self.queue.push(task)
          // リクエストを送信するロジックを実行する self.next()
        }
        次() {
          自分 = これ
          // 実行中のタスク数が同時実行数より少ない場合、タスクの実行を継続します while(self.runing < pool && self.queue.length) {
            自己実行++;
            // これはタスクを取得して削除するのと同じです。let task = self.queue.shift();
            // リクエストを実行する task().then(result => {
              //実行結果を保存する self.results.push(result)
            }).finally(() => {
              // 実行中の項目の数をクリアする self.runing--
              // リクエストの実行を続行する self.next()
            })
          }
          // タスクがない場合はループが終了します if(self.runing === 0) callback(self.results)
        }


      }
      // インスタンス化 let TQ = new TaskQueue()
      タスクごとにタスクを実行します。
    }


    リクエストを作成します(タスク、2、結果=> {
      console.log(結果);
    })

要約する

上記は、この一連のインタビューの質問の要約です。私自身もメモしました。今後もフロントエンドの記事を更新し続けます。最後に、フロントエンドの友人全員が学習を継続し、スキルを継続的に向上させることができることを願っています。さあ、若者よ! ! !

JS ベースの Ajax 同時リクエスト制御の実装方法に関するこの記事はこれで終わりです。JS による Ajax 同時リクエスト制御の実装に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • リクエスト数を制限するために Ajax 同時リクエストを実装するために js を使用するサンプル コード
  • ByteDance インタビュー: JS を使用して Ajax 同時リクエスト制御を実装する方法

<<:  Nginx セッション損失問題の解決策

>>:  MySql5.x を MySql8.x にアップグレードする方法と手順

推薦する

JavaScript関数の詳細な紹介

任意の数のステートメントを関数を通じてカプセル化することができ、いつでもどこでも呼び出して実行できま...

シンプルなウェブ計算機を実装するJavaScript

背景私は新しいプロジェクト チームに配属されたので、プロジェクトでは js を使用する必要があります...

node.js で EventEmitter をカスタマイズする方法

目次序文1. 何ですか2. Node.jsでEventEmitterを使用する方法3. 実施プロセス...

Vue3 ドラッグ可能な左パネルと右パネルの分割コンポーネントの実装

目次コンポーネントの分解左パネル右パネル入力パラメータの分解小道具スロット具体的な実装ドラッグする方...

AIX マウント NFS の書き込み効率が低い場合の解決策

NFSが提供するサービスマウント: サーバー上で /usr/sbin/rpc.mountd サーボ ...

WEBAPP開発スキルのまとめ(モバイルWebサイト開発の注意点)

1. レスポンシブな Web を開発するには、ページを画面サイズに適応させる必要があります。前の記...

MySQL 5.7.17 圧縮バージョンのインストールノート

この記事では、参考までにMySQL 5.7.17圧縮版のインストール手順を紹介します。具体的な内容は...

MySQL 5.7.20 Green Edition のインストールの詳細なグラフィックチュートリアル

まず、MySQL とは何かを理解しましょう。 MySQL は、スウェーデンの会社 MySQL AB ...

Azure Container Registry を使用してイメージを保存する際の問題

Azure Container Registry は、Docker Registry 2.0 仕様に...

Linuxファイル削除後にスペースが解放されない問題の詳しい説明

序文システム領域の使用量が大きすぎて消去する必要がある場合、または特定のファイルを消去する必要がある...

css3 flexレイアウト justify-content:space-between 最後の行は左揃えになります

justify-content:space-betweenレイアウトを使用する場合、要素の最後の行に...

HTML 形式の JSON 出力の例 (テスト インターフェース)

JSON データを美しいインデント形式で表示するには、最も単純な JSON.stringify 関...

mysql-8.0.15-winx64 解凍バージョンのインストールチュートリアルと終了する 3 つの方法

1.公式サイトからダウンロードして解凍する参考: 2. 環境変数を設定するMYSQL_HOMEをMy...

HTML初心者や初級者向けの提案。専門家は無視してかまいません。

感想:私はバックエンド開発者です。静的 (HTML) ページを取得すると、ページ構造と命名規則が極端...

HTML Selectは、デフォルトの選択を設定するためにselected属性を使用します。

オプションに属性 selected = "selected" を追加すると、それ...