iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >JavaScript中实现并发控制的方法
  • 884
分享到

JavaScript中实现并发控制的方法

2023-06-15 16:06:40 884人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关javascript中实现并发控制的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、并发控制简介在日常开发过程中,你可能会遇到并发控制的场景,比如控制请求并发数。那么在

这篇文章将为大家详细讲解有关javascript中实现并发控制的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一、并发控制简介

在日常开发过程中,你可能会遇到并发控制的场景,比如控制请求并发数。那么在 JavaScript  中如何实现并发控制呢?在回答这个问题之前,我们来简单介绍一下并发控制。

假设有 6 个待办任务要执行,而我们希望限制同时执行的任务个数,即最多只有 2 个任务能同时执行。当 正在执行任务列表 中的任何 1  个任务完成后,程序会自动从 待办任务列表 中获取新的待办任务并把该任务添加到 正在执行任务列表 中。为了让大家能够更直观地理解上述的过程,阿宝哥特意画了以下 3  张图:

1.1 阶段一

JavaScript中实现并发控制的方法

2 阶段二

JavaScript中实现并发控制的方法

3 阶段三

JavaScript中实现并发控制的方法

好的,介绍完并发控制之后,阿宝哥将以 GitHub 上 async-pool 这个库来介绍一下异步任务并发控制的具体实现。

https://github.com/rxaviers/async-pool    Run multiple promise-returning & async functions with limited concurrency using native es6/ES7。

 二、并发控制的实现

async-pool 这个库提供了 ES7 和 ES6 两种不同版本的实现,在分析其具体实现之前,我们来看一下它如何使用。

2.1 asyncPool 的使用

const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i)); await asyncPool(2, [1000, 5000, 3000, 2000], timeout);

在以上代码中,我们使用 async-pool 这个库提供的 asyncPool 函数来实现异步任务的并发控制。asyncPool 函数的签名如下所示:

function asyncPool(poolLimit, array, iteratorFn){ ... }

该函数接收 3 个参数:

  • poolLimit(数字类型):表示限制的并发数;

  • array(数组类型):表示任务数组;

  • iteratorFn(函数类型):表示迭代函数,用于实现对每个任务项进行处理,该函数会返回一个 Promise 对象或异步函数。

对于以上示例来说,在使用了 asyncPool 函数之后,对应的执行过程如下所示:

const timeout = i => new Promise(resolve => setTimeout(() => 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]`.

通过观察以上的注释信息,我们可以大致地了解 asyncPool 函数内部的控制流程。下面我们先来分析 asyncPool 函数的 ES7 实现。

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 对象变成已完成状态时,才会调用 enqueue 函数,从 array 数组中获取新的待办任务。

三、阿宝哥有话说

在 asyncPool 这个库的 ES7 和 ES6 的具体实现中,我们都使用到了 Promise.all 和 Promise.race  函数。其中手写 Promise.all 是一道常见的面试题。刚好趁着这个机会,阿宝哥跟大家一起来手写简易版的 Promise.all 和  Promise.race 函数。

3.1 手写 Promise.all

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 对象 resolved 或  rejected,返回的 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);         });     }   }); };

关于“JavaScript中实现并发控制的方法”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: JavaScript中实现并发控制的方法

本文链接: https://www.lsjlt.com/news/280936.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript中实现并发控制的方法
    这篇文章将为大家详细讲解有关JavaScript中实现并发控制的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、并发控制简介在日常开发过程中,你可能会遇到并发控制的场景,比如控制请求并发数。那么在 ...
    99+
    2023-06-15
  • JavaScript中怎么实现并发控制
    这篇文章给大家分享的是有关JavaScript中怎么实现并发控制的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 在日常开发过程中,你可能会遇到并发控制...
    99+
    2022-10-19
  • JavaScript中如何实现并发控制
    这篇文章将为大家详细讲解有关JavaScript中如何实现并发控制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、前言在开发过程中,有时会遇到需要控制任务...
    99+
    2022-10-19
  • JavaScript 中如何实现并发控制
    目录一、并发控制简介1.1 阶段一1.2 阶段二1.3 阶段三二、并发控制的实现2.1 asyncPool 的使用2.2 asyncPool ES7 实现2.3 asyncPool ...
    99+
    2022-11-12
  • MySQL 加锁控制并发的方法
    前言 锁总体可以分为乐观锁和悲观锁,简单说,乐观锁用版本号控制,悲观锁用锁控制。 下面是待会要用来测试的数据 # 添加一个user表 CREATE TABLE `users` ( `id` int(11) N...
    99+
    2022-05-14
    MySQL 加锁 MySQL 并发
  • Golang 语言控制并发 Goroutine的方法
    goroutine 是 Go语言中的轻量级线程实现,由 Go 运行时(runtime)管理。Go 程序会智能地将 goroutine 中的任务合理地分配给每个 CPU。 01介绍 G...
    99+
    2022-11-12
  • golang并发控制的方法是什么
    在Go语言中,可以使用以下几种方法来控制并发:1. Goroutine:Goroutine是Go语言中的轻量级线程,可以通过go关键...
    99+
    2023-10-20
    golang
  • js Promise并发控制数量的方法
    目录问题背景思路 & 实现问题 要求写一个方法控制 Promise 并发数量,如下: promiseConcurrencyLimit(limit, array, ite...
    99+
    2022-11-12
  • MySQL中怎么实现并发控制
    今天就跟大家聊聊有关MySQL中怎么实现并发控制,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。锁锁分为读锁和写锁两种,也称作共享锁和排他锁。因为多个...
    99+
    2022-10-18
  • MySQL的多版本并发控制MVCC实现方法是什么
    这篇文章主要讲解了“MySQL的多版本并发控制MVCC实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL的多版本并发控制MVCC实现方法是什么”吧!什么是MVCCMVCC...
    99+
    2023-06-22
  • golang控制并发数的方法是什么
    在Golang中,可以使用goroutine和channel来控制并发数。以下是几种常见的方法: 通过控制goroutine的数...
    99+
    2023-10-27
    golang
  • golang控制并发数量的方法是什么
    在golang中,可以使用goroutine和channel来控制并发数量。以下是一些常用的方法: 使用goroutine和Wai...
    99+
    2023-10-21
    golang
  • golang控制并发数怎么实现
    在Go语言中,可以使用goroutine和channel来实现并发控制。下面是一种常见的实现方式: 创建一个有缓冲的channel...
    99+
    2023-10-21
    golang
  • mysql多版本并发控制MVCC的实现
    事务隔离级别设置 set global transaction isolation level read committed; //全局的 set session transaction isolat...
    99+
    2022-10-18
  • mysql的MVCC多版本并发控制的实现
    1 什么是MVCC MVCC全称是: Multiversion concurrency control,多版本并发控制,提供并发访问数据库时,对事务内读取的到的内存做处理,用来避免写操作堵塞读操作的并发问题。 举个...
    99+
    2022-05-31
    mysql MVCC多版本并发控制 mysql 多版本并发控制
  • MySQL的多版本并发控制MVCC的实现
    目录什么是MVCC MVCC的实现 MVCC 有没有解决幻读? 什么是MVCC MVCC就是多版本并发控制。 MySQL的事务型存储引擎通过多版本并发控制(MVCC)来提升并发性...
    99+
    2022-11-12
  • Javascript如何实现动态样式控制方法
    这篇文章主要介绍Javascript如何实现动态样式控制方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!方法一:使用style属性来设置使用style属性来设置html代码:   &n...
    99+
    2023-06-29
  • MySQLMVVC多版本并发控制的实现详解
    目录一、概述二、快照读与当前读1.当前读2.快照读三、隔离级别与版本链复习四、Read View1.实现原理2.Read View规则3.整体流程五、举例1.READ2.REPEAT...
    99+
    2022-11-13
  • Java高并发下的流量控制方法是什么
    今天小编给大家分享一下Java高并发下的流量控制方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。这个时候如果不做任何...
    99+
    2023-06-16
  • 如何在Java和Django中实现高效的并发控制?
    随着互联网的快速发展,高并发的情况越来越普遍。在Java和Django中实现高效的并发控制是非常重要的。在本文中,我们将介绍一些在Java和Django中实现高效的并发控制的方法,并提供相应的代码演示。 一、Java中的并发控制 在Java...
    99+
    2023-09-10
    django 同步 并发
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作