-
Notifications
You must be signed in to change notification settings - Fork 88
ES6 中引入了 Generator
,Generator
通过封装之后,可以作为协程来进行使用。
其中对 Generator
封装最为著名的当属 co
,但是 co
跟 ES2016 的 async/await 相比的话,还存在一些比较严重的缺陷。
hprose 中也引入了对 Generator
封装的协程支持,而且比 tj 的 co
更加完善,后面我们会详细介绍它们之间的一些差别。
下面先让我们来看一个例子:
var hprose = require('hprose');
hprose.co(function*() {
var client = hprose.Client.create('http://hprose.com/example/');
yield client.useService();
console.log(yield client.hello("World"));
});
hprose.co
(也可以是 hprose.Future.co
)就是一个协程封装函数。它的功能是以协程的方式来执行生成器函数。该方法允许带入参数执行。
在上面的例子中,client
是一个 Hprose 的 HTTP 客户端。Hprose 的 JavaScript 版本(包括 NodeJS, HTML5, JavaScript 和微信小程序专用版)的客户端为异步客户端,所以它上面的调用都是异步调用。
因为 JavaScript 的 Proxy
(中文版) 具有浏览器兼容性问题,所以在客户端代理对象的生成上,使用的是动态获取服务列表的方式来实现的。
上面的 yield client.useService()
语句就是用于返回这个客户端代理对象,使用默认参数调用时,会将 client
对象本身设置为代理对象,因此这里我们没有使用返回值,如果要在其它地方使用的话,最好是保存它的返回值。
client.useService()
的返回值是一个 Promise
对象,如果不使用协程,那么在使用时,需要使用 then
方法,然后在其回调中才能使用,而使用协程,直接使用 yield
就可以获得实际的代理对象了。而且因为在这里 client
本身就是代理对象,因此当 yield
返回代理对象之后,client
对象就已经被初始化好了,因此后面就可以直接调用 client
上的 hello
方法了。
client
的 hello
方法的返回值也是个 Promise
对象,使用 yield
之后,它的返回值就变成了实际值,也就可以直接用 console.log
进行打印了。
通过上面的例子,我们可以看出,使用协程方式,Hprose 调用就被完全同步化了。这可以大大简化异步程序的编写。