协程
进程和线程我们都知道,那么协程是什么呢?
协程是一种比线程更加轻量级的存在。可以把协程看成是跑在线程上的任务,一个线程上可以存在多个协程,但是在线程上同时只能执行一个协程,比如当前执行的是 A 协程,要启动 B 协程,那么 A 协程就需要将主线程的控制权交给 B 协程,这就体现在 A 协程暂停执行,B 协程恢复执行;同样,也可以从 B 协程中启动 A 协程。通常,如果从 A 协程启动 B 协程,我们就把 A 协程称为 B 协程的父协程。
正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。最重要的是,协程不是被操作系统内核所管理,而是完全由程序所控制(即在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。
执行过程如下图所示,可以重点关注协程之间的切换
从图中可以看出来协程的四点规则:
通过调用生成器函数
genDemo
来创建一个 协程gen
,创建之后,gen
协程并没有立即执行。要让
gen
协程执行,需要通过调用gen.next
。当协程正在执行的时候,可以 通过
yield
关键字来暂停gen
协程的执行,并返回主要信息给父协程。如果协程在执行期间,遇到了
return
关键字,那么 JS 引擎会结束当前协程,并将return
后面的内容返回给父协程。
协程之间的切换:
gen
协程和父协程是在主线程上交互执行的,并不是并发执行的,它们之前的切换是 通过yield
和gen.next
来配合完成 的。当在
gen
协程中调用了yield
方法时,JS 引擎会保存gen
协程当前的调用栈信息,并恢复父协程的调用栈信息。同样,当在父协程中执行gen.next
时,JS 引擎会保存父协程的调用栈信息,并恢复gen
协程的调用栈信息。
其实在 JS 中,Generator
生成器就是协程的一种实现方式。
最后更新于