napajs实现了JS世界中的多线程,zone是napajs中重要的概念,它是逻辑上运行特定任务的一组对称的worker。
注意:这里的区域(zone)不同于在Dart、Angular中异步调用的上下文对象,也不同于TC39(技术委员会39)的提议。
zone由一个或者多个JavaScript组成,每个线程被称为一个worker。同一个zone里的worker是幂等的(对等的),也就是说在该zone里的任意一个worker上执行返回相同的结果,而且从长远来看,每一个worker的内部状态应该相同。
同一个进程中可以同时存在多个zone,每个zone载入不同的代码,呈现不同的状态或者应用不同的策略,例如堆的大小等。存在多个zone的目的是允许执行多角色的复杂任务,每个角色加载供自身使用的最少的资源。
有两种类型的zone:
在zone上可以执行两种操作:
根据字符类型的id创建一个Napa zone。如果该id的zone已经存在,会抛错。ZoneSettings能设置创建的zone。
例如1:创建一个id为‘zone1’的zone,使用默认设置。
var napa = require('napajs');var zone1 = napa.zone.create('zone1');例如2:创建一个id为‘zone2’的zone,包含一个worker。
var zone2 = napa.zone.create('zone2', { workers: 1});该方法通过id获得一个zone的引用。如果该zone不存在,抛错。 例如:
var zone = napa.zone.get('zone1');
该方法返回当前运行的zone的引用。如果正在node下,则返回node zone。 例如:获得当前zone。
var zone = napa.zone.current;
该方法返回node zone的引用,等价于napa.zone.get('node') 例如:
var zone = napa.zone.node;zone的设置在创建是就会指定好。如果没有指定,则使用默认设置DEFAULT_SETTINGS。
zone中的worker的数量
创建zone时的默认配置:
{ workers: 2}在Napa中,zone是执行JS和应用策略的基本概念。可以在简介中找到它的定义。通过Zone API,开发者可以在所有的worker间广播JS代码,或者在某个worker上执行一个方法。当你针对一个zone编程的时候,最好确保该zone内的所有的worker之间是幂等的(对等的),因为我们不能假设一个worker能够自己维持自身的状态。
两个主要的API集合是broadcast和execute,它们都是带有入参的异步的操作。
该方法可以获得zone的id
该方法以字符串的形式向所有worker异步广播一个JS代码片段,并得到一个空的Promise句柄返回。如果存在任意一个worker执行该代码段失败,promise句柄会抛出错误。
例如:
var napa = require('napajs');var zone = napa.zone.get('zone1');zone.broadcast('var state = 0;') .then(() => { console.log('broadcast succeeded.'); }) .catch((error) => { console.log('broadcast failed.') });该方法向所有的worker异步广播一个带有入参的匿名函数,并返回一个空的Promise句柄。如果存在任意一个worker执行该函数失败,句柄promise将会抛错。
*注意:在广播时Napa 函数不支持闭包
例如:
zone.broadcast((state) => { require('some-module').setModuleState(state) }, [{field1: 1}]) .then(() => { console.log('broadcast succeeded.'); }) .catch((error) => { console.log('broadcast failed:', error) });通过模块名和函数名在某一worker上异步执行一个函数。入参是可传递的任意JS类型。该方法返回一个名为Result的句柄。不论是不友好的代码、用户异常或者发生超时导致的错误,句柄都会被拒绝。 例如:执行‘foo’模块的‘bar’方法,传入的参数是[1,'hello',{field:1}],使用300ms的延迟。
zone.execute( 'foo', 'bar', [1, "hello", {field1: 1}], { timeout: 300 }) .then((result) => { console.log('execute succeeded:', result.value); }) .catch((error) => { console.log('execute failed:', error); });该方法是在任意一个worker上异步执行一个方法对象。入参是可传递的任意JS类型。该方法返回一个名为Result的句柄。不论是不友好的代码、用户异常或者发生超时导致的错误,句柄都会被拒绝。 在执行方法对象时有一些限制: 方法对象不能访问闭包里的变量 如果函数对象没有指定origin属性,则把当前文件作为origin,origin可以设置 __filename 和 __dirname。(详见transporting functions)
例如:
zone.execute((a: number, b: string, c: object) => { return a + b + JSON.stringify(c); }, [1, "hello", {field1: 1}]) .then((result) => { console.log('execute succeeded:', result.value); }) .catch((error) => { console.log('execute failed:', error); });输出:
execute succeeded: 1hello{"field1":1}
下面的例子说明了当执行异步函数时如何访问 __filename:
// File: /usr/file1.jszone.execute(() => { console.log(__filename);});输出:
/usr/file1.js
zone.execute的回调函数操作接口
超时时间为毫秒,默认值0表示没有延迟。
访问execute返回结果的接口
result.value是被zone.execute和zone.executeSync调用的函数返回的JavaScript值。Napa在不同的worker之间编组/解组可传递的值。解组发生在第一次查询result.value时。
例如:
var value = result.value;result.payload是返回值编组的载荷(以JSON的形式)。该接口使用户可以在不需要解组的地方将结果传递给它的调用者。
例如:
var payload = result.payload;TransportContext是指要求将result.payload解组成result.value。
例如:
var napa = require('napajs');var zone = napa.zone.create('zone1');zone.execute(() => { return 0; }, []) .then((result) => { // Manually marshall. var transportContext = result.transportContext; var value = napa.transport.unmarshall(result.payload, result.transportContext); // result.value and manual unmarshall from payload are the same. assert.equal(value, result.value); });
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删