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

2018-06-24 01:05:42来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

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

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Vue.js 2.x Development Build With Hot Reloading For External

下一篇:精心收集的 48 个 JavaScript 代码片段,仅需 30 秒就可理解!