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

推薦する

HTMLを教える記事

アーティストになるつもりがない場合は、開発者として HTML を読んで、必要に応じて簡単な変更を加え...

CentOS 7.3 で Nginx 仮想ホストを設定する方法

実験環境最小限にインストールされた CentOS 7.3 仮想マシン基本環境を構成する1. ngin...

DockerにMinIOをインストールするための詳細な手順

目次1. docker環境が正常かどうかを確認する2. miniIOイメージをダウンロードする3. ...

WHMCS V7.4.2 グラフィカル インストール チュートリアル

1. はじめにWHMCS は、ユーザー管理、請求書の支払い、ヘルプ サービスなど、オンライン ビジネ...

Spring Boot + jar パッケージングのデプロイメント Tomcat 404 エラーの問題を解決する

1. Spring Boot は jsp jar パッケージをサポートしていません。jsp は wa...

画像の下部の空白部分の問題を解決する

最近のプロジェクトに取り組んでいるとき、下の図に示すように、画像を参照すると常に下部に空白スペースが...

MacBook 向け Python 3.7 インストール チュートリアル

MacBookにpython3.7.0をインストールする詳細な手順は、参考までに記録されています。具...

MySQLの大文字と小文字の区別によって発生する問題の分析

MYSQLは大文字と小文字を区別します言葉を見れば信じられます。タイトルを見れば内容がわかります。 ...

CentOS での MySQL ログイン 1045 問題を解決する

アプリケーション全体を CentOS にデプロイする必要があるため、当然ながらデータベース操作は不可...

インデックスは MySQL クエリ条件で使用されますか?

雇用主から MySQL クエリ条件でインデックスが使用されるかどうかを尋ねられた場合、どのように答え...

Django が uwsgi+nginx プロキシで静的リソースにアクセスできない問題の解決方法

uwsgi+nginx プロキシ Django をデプロイする場合、uwsgi を使用したアクセスは...

MySQL の自動増分主キーが使い果たされた場合の対処方法

面接では、次のようなシナリオを経験する必要があります。インタビュアー: 「MySQL を使用したこと...

jsフェッチ非同期リクエストの使用の詳細な例

目次非同期を理解するフェッチ(url)レスポンス.json() asyncとawaitを組み合わせる...

NestJsはMongooseを使用してMongoDBを操作する

最近、NestJs フレームワークを学び始めました。学習コストは他のフレームワークよりもはるかに高く...

重複したMySQLテーブルをマージして削除する簡単な方法

シナリオ:クロールされたデータは、別のメインテーブルと同じ構造を持つデータテーブルを生成するため、マ...