协程,英文名coroutine,是一种执行过程可以被暂停和恢复的方法。各个协程之间相互协作完成一个任务。

让我们来看一个关于发挥协程作用的例子。假定我们有一个生产者和消费者的关系,生产者创建物品并将物品添加到一个队列,消费者从队列中取出物品并使用该物品。为了提高效率,生产者会一直创建并添加物品,直到队列满为止,队列满时通知运行环境调用消费者;消费者会一直取出并使用物品,直到队列空为止,队列空时通知运行环境调用生产者。下面是使用协程实现这个关系的伪代码:

var q := new queue
coroutine produce
loop
while q is not full
create some new items
add the items to q
yield to consume
coroutine consume
loop
while q is not empty
remove some items from q
use the items
yield to produce

在这段代码中,produce和consume不是普通的方法,而是由关键字coroutine被定义成为协程。当运行环境执行produce时,produce会在队列满时通过yield主动放弃执行权,并告知运行环境去调用consume协程。同样,consume协程在队列空时也会通过yield主动放弃执行权,并告知运行环境去调用produce协程。

在介绍什么是协程之后,接下来我将讲协程在ES6中的实现方式。ES6提供了一种新的方法名叫Generator。Generator的执行过程可以被暂停和恢复,所以它被认为是ES6中的协程,但严格地说,Generator只是半协程(semi-coroutine),因为虽然它可以主动放弃执行权,但是它并没有告知运行环境,下一步哪个协程会被调用。当一个Generator被调用时,它的代码并不会被执行,调用者得到的是它的观察者(Observer)。调用者通过调用这个观察者的方法,比如next方法,来执行Generator的代码。

下面是通过Generator实现上述生产者和消费者关系的ES6代码:

 const Q = [];
const Q_LEN = 10; function* produce() {
while (Q.length < Q_LEN) {
const item = Date.now();
Q.push(item);
console.log(`Item ${item} is produced`); if (Q.length === Q_LEN) {
yield;
}
}
} function* consume() {
while (Q.length > 0) {
const item = Q.pop();
console.log(`Item ${item} is consumed`); if (Q.length === 0) {
yield;
}
}
} function bootstrap() {
const producer = produce();
const consumer = consume(); while(true) {
producer.next();
consumer.next();
}
} bootstrap();

在上面代码中,produce和consume是两个协程。bootstrap方法是这两个协程的调用者,它首先获取produce和consume协程的观察者,然后循环调用观察者的next方法,从而使得生产者和消费者的关系持续运行。在循环过程中,如果produce检测队列已满,它就主动放弃执行权从而被暂停,consume将获得执行权,如果consume检测队列已空,它就主动放弃执行权从而被暂停,produce将重新获得执行权。

好了,上文简单介绍了什么是协程及其在ES6中的实现方式,希望它能对在理解协程和在ES6中使用协程产生疑问的人有所帮助,谢谢。

参考

  • https://en.wikipedia.org/wiki/Coroutine

简单介绍什么是协程及其在ES6中的实现方式的更多相关文章

  1. 协程在Web服务器中的应用(配的图还不错)

    协程(纤程,微线程)这个概念早就有之,各家互联网公司也都有研究,但在国内各大论坛和大会热起来,还是今年的事. 最近参与讨论开放平台建设和架构设计过程中,有同事提到了使用协程代替线程,能够很大幅度的提高 ...

  2. [转]Unity3D协程介绍 以及 使用

    作者ChevyRay ,2013年9月28日,snaker7译  原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...

  3. {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二

    python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ...

  4. Unity3D协程介绍 以及 使用

    作者ChevyRay ,2013年9月28日,snaker7译  原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...

  5. Python中异步协程的使用方法介绍

    1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后 ...

  6. 带你简单了解python协程和异步

    带你简单了解python的协程和异步 前言 对于学习异步的出发点,是写爬虫.从简单爬虫到学会了使用多线程爬虫之后,在翻看别人的博客文章时偶尔会看到异步这一说法.而对于异步的了解实在困扰了我好久好久,看 ...

  7. Unity3D 协程的介绍和使用

    我是快乐的搬运工 http://blog.csdn.net/u011397120/article/details/61236055 ---------------------------------- ...

  8. spawn协程学习

    对于IO密集型的程序,一般比较高效的做法是选择异步来实现,因为使用异步的方法更容易写出高效的程序.然而使用异步的话,经验较少的人往往会使自己的程序结构变得很混乱,进而导致程序的可读性变差.记得有人说过 ...

  9. [转载]Python 3.5 协程究竟是个啥

    http://blog.rainy.im/2016/03/10/how-the-heck-does-async-await-work-in-python-3-5/ [译] Python 3.5 协程究 ...

随机推荐

  1. Adobe阅读器漏洞(adobe_cooltype_sing)学习研究

    实验环境:Kali 2.0+Windows XP sp3+Adobe Reader 9.0.0 类别:缓冲区溢出 描述:这个漏洞针对Adobe阅读器9.3.4之前的版本,一个名为SING表对象中一个名 ...

  2. Java注解Annotation详解

    从JDK5开始,Java增加了Annotation(注解),Annotation是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行相应的处理.通过使用Annotation,开发人员可 ...

  3. git使用(上)-----基本的方法

    git应该是一项必须要掌握的工具.先简述它和SVN的区别 SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活 ...

  4. 边框(Border) 和 轮廓(Outline) 属性

    border 复合属性.设置对象边框的特性. 标签定义及使用说明 如果上述值缺少一个没有关系,例如border:#FF0000;是允许的. 默认值: not specified 继承: no Java ...

  5. C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...

  6. GO学习——安装编译(1)

    学习网站列表: Golang官网:https://golang.org/ Golang标准库文档:https://golang.org/pkg Golang中文标准库文档:https://studyg ...

  7. numpy中关于*和dot的区别

    1.numpy乘法运算中"*"是数组元素逐个计算 >>> import numpy as np >>> a = np.array([[2,3], ...

  8. 前端页面适配的rem换算

    为什么要使用rem 之前有些适配做法,是通过js动态计算viewport的缩放值(initial-scale). 例如以屏幕320像素为基准,设置1,那屏幕375像素就是375/320=1.18以此类 ...

  9. day7、用户登陆出现-bash-4.1$错误的原因

    有时候在使用用户登陆Linux系统时会出现-bash-4.1$错误,不显示用户名,路径信息. 原因:用户家目录里面与环境变量有关的文件被删除所导致的 .bash_profile .bashrc 这两个 ...

  10. 大白话Vue源码系列(03):生成AST

    阅读目录 AST 节点定义 标签的正则匹配 解析用到的工具方法 解析开始标签 解析结束标签 解析文本 解析整块 HTML 模板 未提及的细节 本篇探讨 Vue 根据 html 模板片段构建出 AST ...