并发任务控制

认识并发任务控制

  1. 什么是并发?

因为 js 是单线程的,所以前端的并发指的是在极短时间内发送多个数据请求,比如说循环中发送 ajax。

  1. 前端为什么要控制并发?

前端需要控制并发的主要原因有:

  1. JS 单线程:JS 是单线程执行的,同一时间只能做一件事。如果有太多异步任务同时执行,会导致主线程被阻塞,影响页面性能。控制并发可以避免这种情况。
  2. 资源限制:浏览器资源有限,如 CPU、内存、网络等。如果太多任务同时执行,很容易导致页面卡顿甚至崩溃。控制并发可以保证在资源负载限制内正常执行。
  3. 防止互相影响:很多时候异步任务会操作相同的 DOM 元素或变量,如果同时执行很容易产生未定义的行为和莫名的 bug。控制并发可以避免这类问题。
  4. 代码可维护性:大量异步任务同时执行会让代码变得很难追踪和调试。控制并发让任务有序执行,可以大大提高代码的可读性和可维护性。
  5. 优先级:有些任务的优先级更高,需要先执行。并发控制可以根据优先级决定任务执行顺序。
  6. 错误处理:如果多个异步任务同时出错,很难定位具体错误原因。控制并发意味着每个任务都是在正常状态下执行的,如果出现错误也更容易捕获和处理。

所以总之,由于 JS 的单线程模型和浏览器资源限制,前端需要并发控制来确保程序的性能、稳定性和可维护性。控制异步任务的执行顺序,可以最大化的利用资源并避免各种意想不到的问题。这也是前端工程师需要掌握的一个很重要的技能。

思考

我们已经了解了什么是并发,以及为什么要控制并发。那么就让我看下图中的一道题,来完成要求,实现一个异步任务的调度器。

并发任务控制

从上面的代码我们可以看出,图中需要我们去实现的是 SuperTask 类,这个类的作用是控制异步任务的调用,类中有一个 add 的方法,来添加异步任务,add 返回一个 Promise。

通过 addTask 的五次调用我们发现,每次只有两个异步任务在执行,完成一个异步任务后,会有一个新的任务被调用执行,如下图所示。

并发任务控制

现在基本逻辑我们已经清楚,那么我们去实现一下吧!

实现

并发任务控制

根据思考中的描述,我们有了大概的方向,所以有了上图中的代码,那么还有一些问题我们没有思考到,比如何时判断执行队列中的任务已完成要调用新的任务呢?

可能有些同学会说,我们可以直接在 add 函数中直接调用 task 啊?可是如果我们直接调用的话,当前执行队列中如果已经有两个了怎么办呢?所以在 add 函数中直接调用显然是不可取的,那么既然 add 中不可取,那就只能由一个新的函数负责了。

那么新的问题又出现了,我们怎么知道任务何时成功与失败呢?在上图中我们仅仅将任务放在了任务队列中,并无法知道任务的状态,所以我们在向任务队列中添加任务的同时也要将状态加入其中。

那么让我们来改造一下代码。

并发任务控制

改造完代码之后,我们就剩下实现 _run 函数了,首先我们要搞清楚,_run 到底要实现什么目标,其实也很简单就是依次运行任务队列里的所有任务,那很明显 _run 函数里应该是一个循环,那么我们应该使用什么循环合适呢?让我们思考一下,在循环之前我们肯定是要判断当前执行队列里的任务是否小于可允许并发数量以及任务队列是否还有数据,那么既然是先判断后循环 while 在这里就是最合适的了,那么我们去实现一下。

并发任务控制

到这里我们就完成啦!

并发任务控制

那么让我们在浏览器里运行一起看看结果吧。

并发任务控制

总结

我们写到最后其实已经发现了,这道题考察的就是最原始的 JS 代码,我们常常在工作中使用各种框架以及各种第三方库,往往会疏忽我们最基础的 JS,俗话说:‘基础不牢,地动山摇’,牢固的语言基础和理论基础,配合实践经验,才是我们成为一名优秀前端工程师的关键。

备注:学习来源 渡一Web前端学习频道

原文链接:https://juejin.cn/post/7223676609793654839 作者:SunshineCK

(0)
上一篇 2023年4月20日 上午10:05
下一篇 2023年4月20日 上午10:16

相关推荐

发表回复

登录后才能评论