Skip to content
小马哥 edited this page Nov 19, 2016 · 28 revisions

基本用法

ES6 中引入了 GeneratorGenerator 通过封装之后,可以作为协程来进行使用。

其中对 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]((http://github.com/hprose/hprose-html5), [JavaScript]((http://github.com/hprose/hprose-js) 和[微信小程序专用版]((http://github.com/hprose/hprose-wx))的客户端为异步客户端,所以它上面的调用都是异步调用。

因为 JavaScript 的 Proxy(中文版) 具有浏览器兼容性问题,所以在客户端代理对象的生成上,使用的是动态获取服务列表的方式来实现的。

上面的 yield client.useService() 语句就是用于返回这个客户端代理对象,使用默认参数调用时,会将 client 对象本身设置为代理对象,因此这里我们没有使用返回值,如果要在其它地方使用的话,最好是保存它的返回值。

client.useService() 的返回值是一个 Promise 对象,如果不使用协程,那么在使用时,需要使用 then 方法,然后在其回调中才能使用,而使用协程,直接使用 yield 就可以获得实际的代理对象了。而且因为在这里 client 本身就是代理对象,因此当 yield 返回代理对象之后,client 对象就已经被初始化好了,因此后面就可以直接调用 client 上的 hello 方法了。

clienthello 方法的返回值也是个 Promise 对象,使用 yield 之后,它的返回值就变成了实际值,也就可以直接用 console.log 进行打印了。

通过上面的例子,我们可以看出,使用协程方式,Hprose 调用就被完全同步化了。这可以大大简化异步程序的编写。

Clone this wiki locally