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 にアップグレードする方法と手順

推薦する

2つのNode.jsプロセスがどのように通信するかの詳細な説明

目次序文異なるコンピュータ上の 2 つの Node.js プロセス間の通信TCPソケットの使用HTT...

MySQL ストアド プロシージャにおけるループ ステートメント (WHILE、REPEAT、LOOP) の使用法の分析

この記事では、例を使用して、MySQL ストアド プロシージャでのループ ステートメント (WHIL...

MySQLのSeconds_Behind_Masterの詳細な説明

目次マスターの後ろの秒数オリジナルの実装最終マスタータイムスタンプマスターとのクロック差他の実行時間...

IE8を閲覧するときにウェブサイトが自動的にIE7互換モードを使用するようにする

序文IE の将来のすべてのバージョンで Web ページの外観が一貫していることを保証するために、IE...

HTML のメタタグの簡単な比較

メタ タグは、ファイル情報を定義し、検索エンジンによる検索を容易にするために Web ページ ファイ...

MySQL 結合テーブルと ID 自動増分の例の分析

結合の書き方左結合を使用する場合、左側のテーブルが必ず駆動テーブルになりますか? 2 つのテーブルの...

Vue の v-model ディレクティブと .sync 修飾子の違いの詳細な説明

目次vモデル.sync微妙な違い機能シナリオを要約します。 vモデル <!--親コンポーネント...

Three.js が Facebook Metaverse 3D ダイナミック ロゴ効果を実現

目次背景メタバースとは何ですか?成果を達成するトライアル 1: THREE.TorusGeometr...

Win7 で IIS7 Web および FTP サービスを完全にアンインストールする方法

昨日、パソコンにPHP開発環境をセットアップした後、Apacheサーバーを再起動するとエラーが続きま...

JavaScript ES6 分割演算子の理解と応用

目次序文脱構築記号の役割使い方分割割り当ての適用アプリケーションの簡単な紹介JSONデータを抽出する...

データベースSQL文の最適化

最適化する理由:実際のプロジェクトが開始され、データベースが一定期間稼働した後、初期のデータベース設...

MySQLインデックスの簡単な分析

データベース インデックスは、テーブル操作の速度を向上させることを目的としたデータ構造です。高速なラ...

js を使用して XML オンライン エディターを作成する例

目次序文オンラインXMLエディタの必要性テクノロジー事前調査ビジュアルプログラミングVSCODEプラ...

SSL で Nginx リバース プロキシを構成する簡単な手順

序文リバース プロキシは、Web 経由で行われたリクエスト (http と https の両方) を...

Vue-cli を使用して Vue プロジェクトを構築する手順の詳細な説明

まず、Vue-cli をインストールする必要があります。 npm インストール -g vue-cli...