码迷,mamicode.com
首页 > 其他好文 > 详细

简单介绍什么是协程及其在ES6中的实现方式

时间:2017-12-18 19:18:22      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:span   循环调用   var   out   循环   cti   blog   body   next   

协程,英文名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代码:

 1 const Q = [];
 2 const Q_LEN = 10;
 3 
 4 function* produce() {
 5     while (Q.length < Q_LEN) {
 6         const item = Date.now();
 7         Q.push(item);
 8         console.log(`Item ${item} is produced`);
 9 
10         if (Q.length === Q_LEN) {
11             yield;
12         }
13     }
14 }
15 
16 function* consume() {
17     while (Q.length > 0) {
18         const item = Q.pop();
19         console.log(`Item ${item} is consumed`);
20 
21         if (Q.length === 0) {
22             yield;
23         }
24     }
25 }
26 
27 function bootstrap() {
28     const producer = produce();
29     const consumer = consume();
30 
31     while(true) {
32         producer.next();
33         consumer.next();
34     }
35 }
36 
37 bootstrap();

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

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

参考

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

简单介绍什么是协程及其在ES6中的实现方式

标签:span   循环调用   var   out   循环   cti   blog   body   next   

原文地址:http://www.cnblogs.com/samupanz18/p/8058625.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!