目次
1.1 Stage 1
1.3 フェーズ 3
2. 同時実行制御の実装
2.1 asyncPool の使用
上記のコードでは、
ES6 実装バージョンでは、コア制御ロジックは、内部的にカプセル化された
3.1 手写 Promise.all
3.2 手写 Promise.race
四、参考资源
ホームページ ウェブフロントエンド jsチュートリアル 同時実行制御とは何ですか? JavaScript で同時実行制御を実装するにはどうすればよいですか?

同時実行制御とは何ですか? JavaScript で同時実行制御を実装するにはどうすればよいですか?

Jun 28, 2021 am 10:50 AM
javascript 同時実行制御

同時実行制御とは何ですか? JavaScript で同時実行制御を実装するにはどうすればよいですか?

日々の開発プロセスでは、同時リクエストの数の制御など、同時実行制御シナリオに遭遇することがあります。では、JavaScript で同時実行制御を実装するにはどうすればよいでしょうか?この質問に答える前に、同時実行制御について簡単に説明しましょう。

実行する To Do タスクが 6 つあり、同時に実行できるタスクの数を制限したいとします。つまり、同時に実行できるタスクは最大 2 つです。 。 実行タスク リストのいずれかのタスクが完了すると、プログラムは自動的にToDoタスク リストから新しいToDoタスクを取得し、そのタスクを実行タスク リストに追加します。 。上記のプロセスを誰もがより直感的に理解できるように、Abago は特別に次の 3 つの絵を描きました:

1.1 Stage 1

同時実行制御とは何ですか? JavaScript で同時実行制御を実装するにはどうすればよいですか?

1.2 フェーズ 2

同時実行制御とは何ですか? JavaScript で同時実行制御を実装するにはどうすればよいですか?

1.3 フェーズ 3

同時実行制御とは何ですか? JavaScript で同時実行制御を実装するにはどうすればよいですか?

# #わかりました、同時実行制御の導入後、アバオ兄弟は Github の async-pool ライブラリを使用して、非同期タスク同時実行制御の具体的な実装を紹介します。

async-pool:https://github.com/rxaviers/async-pool

ネイティブ ES6/ を使用して、制限された同時実行で複数の Promise を返す関数と非同期関数を実行します。 ES7。

2. 同時実行制御の実装

async-pool このライブラリは、ES7 と ES6 の 2 つの異なるバージョンの実装を提供します。具体的な実装については、その使用方法を見てみましょう。

2.1 asyncPool の使用

const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i));
await asyncPool(2, [1000, 5000, 3000, 2000], timeout);
ログイン後にコピー

上記のコードでは、このライブラリ asyncPool# によって提供される async-pool を使用します。 ## 非同期タスクの同時実行制御を実装する機能。 asyncPool 関数のシグネチャは次のとおりです:

function asyncPool(poolLimit, array, iteratorFn){ ... }
ログイン後にコピー

関数は 3 つのパラメータを受け取ります:

    ##poolLimit
  • (数値型): を表します。制限された同時実行数;
  • array
  • (配列タイプ): タスク配列を表します;
  • iteratorFn
  • (関数タイプ): 反復を表します関数、使用 各タスク項目の処理を実装するために、この関数は Promise オブジェクトまたは非同期関数を返します。
  • 上記の例では、
asyncPool

関数を使用した後の、対応する実行プロセスは次のとおりです。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>const timeout = i =&gt; new Promise(resolve =&gt; setTimeout(() =&gt; resolve(i), i)); await asyncPool(2, [1000, 5000, 3000, 2000], timeout); // Call iterator (i = 1000) // Call iterator (i = 5000) // Pool limit of 2 reached, wait for the quicker one to complete... // 1000 finishes // Call iterator (i = 3000) // Pool limit of 2 reached, wait for the quicker one to complete... // 3000 finishes // Call iterator (i = 2000) // Itaration is complete, wait until running ones complete... // 5000 finishes // 2000 finishes // Resolves, results are passed in given array order `[1000, 5000, 3000, 2000]`.</pre><div class="contentsignin">ログイン後にコピー</div></div>上記のアノテーション情報を観察することで、次のことがわかります。

asyncPool

関数内の制御フローを大まかに理解します。まず、asyncPool 関数の ES7 実装を分析しましょう。

「不死へのフルスタックの道」に従って、ブラザー・ア・バオがオリジナルで作成した 4 冊の無料電子書籍 (合計 30,000 ダウンロード) と 50 以上の TS シリーズ チュートリアルを読んでください。

2.2 asyncPool ES7 の実装
async function asyncPool(poolLimit, array, iteratorFn) {
  const ret = []; // 存储所有的异步任务
  const executing = []; // 存储正在执行的异步任务
  for (const item of array) {
    // 调用iteratorFn函数创建异步任务
    const p = Promise.resolve().then(() => iteratorFn(item, array));
    ret.push(p); // 保存新的异步任务

    // 当poolLimit值小于或等于总任务个数时,进行并发控制
    if (poolLimit <= array.length) {
      // 当任务完成后,从正在执行的任务数组中移除已完成的任务
      const e = p.then(() => executing.splice(executing.indexOf(e), 1));
      executing.push(e); // 保存正在执行的异步任务
      if (executing.length >= poolLimit) {
        await Promise.race(executing); // 等待较快的任务执行完成
      }
    }
  }
  return Promise.all(ret);
}
ログイン後にコピー

上記のコードでは、

Promise.all

Promise.race の機能が最大限に活用されています。 . ES7 で提供されている async await 機能と組み合わせることで、ついに同時実行制御機能が実現します。ステートメントの await Promise.race(executing); 行を使用すると、実行タスク リスト 内のより高速なタスクが完了するのを待ってから、次のサイクルの実行を続行します。 asyncPool ES7 の実装は比較的シンプルです。次に、

async await

機能を使用せずに同じ機能を実現する方法を見てみましょう。 2.3 asyncPool ES6 実装

function asyncPool(poolLimit, array, iteratorFn) {
  let i = 0;
  const ret = []; // 存储所有的异步任务
  const executing = []; // 存储正在执行的异步任务
  const enqueue = function () {
    if (i === array.length) {
      return Promise.resolve();
    }
    const item = array[i++]; // 获取新的任务项
    const p = Promise.resolve().then(() => iteratorFn(item, array));
    ret.push(p);

    let r = Promise.resolve();

    // 当poolLimit值小于或等于总任务个数时,进行并发控制
    if (poolLimit <= array.length) {
      // 当任务完成后,从正在执行的任务数组中移除已完成的任务
      const e = p.then(() => executing.splice(executing.indexOf(e), 1));
      executing.push(e);
      if (executing.length >= poolLimit) {
        r = Promise.race(executing); 
      }
    }
 
    // 正在执行任务列表 中较快的任务执行完成之后,才会从array数组中获取新的待办任务
    return r.then(() => enqueue());
  };
  return enqueue().then(() => Promise.all(ret));
}
ログイン後にコピー

ES6 実装バージョンでは、コア制御ロジックは、内部的にカプセル化された

enqueue

関数を通じて実装されます。 Promise.race(executing) によって返された Promise オブジェクトが完了すると、array Get new から enqueue 関数が呼び出されます。配列からの ToDo タスク。 3. A Bao 兄弟から言いたいことがあります

asyncPool

の ES7 および ES6 の特定の実装では、Promise.allおよび Promise.race 関数。その中でも、手書きの Promise.all は面接でよく聞かれる質問です。この機会を利用して、A Bao 兄弟と皆さんは、Promise.all 関数と Promise.race 関数の簡単なバージョンを手書きするようになりました。 <h4 id="手写-Promise-all">3.1 手写 Promise.all</h4><p><strong><code>Promise.all(iterable) 方法会返回一个 promise 对象,当输入的所有 promise 对象的状态都变成 resolved 时,返回的 promise 对象就会以数组的形式,返回每个 promise 对象 resolve 后的结果。当输入的任何一个 promise 对象状态变成 rejected 时,则返回的 promise 对象会 reject 对应的错误信息。

Promise.all = function (iterators) {
  return new Promise((resolve, reject) => {
    if (!iterators || iterators.length === 0) {
      resolve([]);
    } else {
      let count = 0; // 计数器,用于判断所有任务是否执行完成
      let result = []; // 结果数组
      for (let i = 0; i < iterators.length; i++) {
        // 考虑到iterators[i]可能是普通对象,则统一包装为Promise对象
        Promise.resolve(iterators[i]).then(
          (data) => {
            result[i] = data; // 按顺序保存对应的结果
            // 当所有任务都执行完成后,再统一返回结果
            if (++count === iterators.length) {
              resolve(result);
            }
          },
          (err) => {
            reject(err); // 任何一个Promise对象执行失败,则调用reject()方法
            return;
          }
        );
      }
    }
  });
};
ログイン後にコピー

需要注意的是对于 Promise.all 的标准实现来说,它的参数是一个可迭代对象,比如 Array、String 或 Set 等。

3.2 手写 Promise.race

Promise.race(iterable) 方法会返回一个 promise 对象,一旦迭代器中的某个 promise 对象 resolvedrejected,返回的 promise 对象就会 resolve 或 reject 相应的值。

Promise.race = function (iterators) {
  return new Promise((resolve, reject) => {
    for (const iter of iterators) {
      Promise.resolve(iter)
        .then((res) => {
          resolve(res);
        })
        .catch((e) => {
          reject(e);
        });
    }
  });
};
ログイン後にコピー

本文阿宝哥带大家详细分析了 async-pool 异步任务并发控制的具体实现,同时为了让大家能够更好地理解 async-pool 的核心代码。最后阿宝哥还带大家一起手写简易版的 Promise.allPromise.race 函数。其实除了 Promise.all 函数之外,还存在另一个函数 —— Promise.allSettled,该函数用于解决 Promise.all 存在的问题,感兴趣的小伙伴可以自行研究一下。

四、参考资源

更多编程相关知识,请访问:编程视频!!

以上が同時実行制御とは何ですか? JavaScript で同時実行制御を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

Java コレクション フレームワークにおける同時実行制御とスレッド セーフ Java コレクション フレームワークにおける同時実行制御とスレッド セーフ Apr 12, 2024 pm 06:21 PM

Java コレクション フレームワークは、スレッドセーフなコレクションと同時実行制御メカニズムを通じて同時実行を管理します。スレッドセーフなコレクション (CopyOnWriteArrayList など) はデータの一貫性を保証しますが、非スレッドセーフなコレクション (ArrayList など) は外部同期を必要とします。 Java は、ロック、アトミック操作、ConcurrentHashMap、CopyOnWriteArrayList などのメカニズムを提供して同時実行性を制御し、それによってマルチスレッド環境でのデータの整合性と一貫性を確保します。

golang 関数の同時実行制御とサードパーティ ライブラリの統合と拡張 golang 関数の同時実行制御とサードパーティ ライブラリの統合と拡張 Apr 25, 2024 am 09:27 AM

同時プログラミングは、Goroutine と同時実行制御ツール (WaitGroup、Mutex など) を介して Go に実装されており、サードパーティのライブラリ (sync.Pool、sync.semaphore、queue など) を使用してその機能を拡張できます。これらのライブラリは、タスク管理、リソース アクセス制限、コード効率の向上などの同時操作を最適化します。キュー ライブラリを使用してタスクを処理する例では、実際の同時実行シナリオでのサードパーティ ライブラリのアプリケーションを示します。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

See all articles