闯补惫补蝉肠谤颈辫迟异步编程模型的演变19. M: 对应系统线程
P: 调度上下文
G: goroutine(协程)
golang协程介绍
P
G
M2M1
P
G
G
block
M1
G
ip
stack
P
M1
G
ip
stack
可以看到,通过对“协程”上下文(ip,stack)的保存、恢复和调度,使用同步
API编写异步io代码是可行的
30. demo
? 使用yield 执行异步流程
? 这个异步流程可以是一个Promise,也可以是一个Generator
? 存在的问题:
? 如果在setTimeout/setInterval中出现异常,目前并无好办法处理
可以看到,只需要简单的几十行代码,就可以让我们轻松编写异步代码了
Editor's Notes #5: 由于在一般情况下,通过计时器触发的任务,是被动的(系统通知我们代码可以执行),所以通过回调注册可能是唯一合理的方式,这里没有优化的必要。
(这里其实存在一个特例,就是偶尔我们会使用setTimeout来模拟java的Thread.sleep,这个时候,其实是有优化的空间的)
我们主要是考虑,正常的业务代码,请求->响应模式,如何能够避免多层嵌套回调的问题#16: 基于es6之前的javascript语法,promise基本上已经是能够做到的极限了。
那么可以看看其他语言,在近期都有哪些值得我们关注的例子呢。
作为web开发人员,首当其冲的就是node.js#17: 那么说到异步IO,我们自然会想到,作为主流语言的java,我们来看看目前的Java的AIO的api设计
(这里因为还没提到协程的概念,所以暂且不提java中并不特别普及、且未在标准库中支持的协程库)#22: 了解过贰厂6标准的同学应该知道,别蝉6中发布了很多的新特性,#23: 大家都知道,yield 只能在“生成器”(Generator)里写,在其他地方写是无效的。
那为什么叫做“生成器”呢,他“生成”的又是什么呢,所以需要先介绍一下“迭代器”(Iterator)。
PS:迭代器里,还有一个很重要的return对象属性,叫做return.这个是在for of循环异常结束的时候(没有next到done:true的时候),会执行。通常用作给迭代器闭包里的对象、资源做释放。但是由于和今天的主题关系不大,就此略去
#28: 生成器内部可以try,catch捕获异常
生成器对象具有throw方法,外部可以通过这个方法,向内部生成器函数抛出一个error,并被内部捕获
如果异常在内部没有捕获(不管是内部自己抛出的,还是外部通过generator.throw抛出的),就会自动抛出到外面,外面的函数通过try可以捕获到
通过generator.throw抛出的异常,被内部捕获到之后,内部会自动调一次next方法(此时生成器没有结束,还是可以继续的)
如果内部有异常没有捕获,这个函数就不会再执行下去,再调用next,将返回value:undefind,done:true的迭代器
除了异常处理,generator.return的参数将作为生成器返回的value
return之后,生成器将返回done:true
相当于外部可以强制结束一个生成器函数的执行
#29: 前面都是铺垫,下面一起看下如何实现一个具备基本功能的异步编程库