在节点中使用zone.js钩子

我正在尝试在节点中使用angular / zone.js编写一个简单演示,但由于某种原因, beforeTaskafterTask都不会被调用。

这是我正在运行的代码:

 require('zone.js'); function foo () { Zone.current.fork({ name: 'foo_zone', beforeTask: function () { console.log('~~~ ZONE START ~~~'); }, afterTask: function () { console.log('~~~ ZONE END ~~~'); } }) .run(function () { console.log('in the zone'); console.log('Zone.current.name', Zone.current.name); // prints foo_zone setTimeout(() => { console.log('timeout is up'); }, 1000); }); } foo(); 

现在在区域内的一切都打印好,包括区域名称,但没有被调用的钩子。

我是否缺less一些基本的zone.js + node.js?

(运行节点v5.0.0,zone.js 0.6.23)

这是示例存储库。 https://github.com/JiaLiPassion/zone-node

首先,您需要使用最新版本的zone.js并在nodejs中使用zone.js,则应该要求zone-node.js,以下是一个正在运行的示例。

 require('./zone-node.js'); function log(str) { Zone.root.run(function() { console.log(str); }); } function foo() { Zone.current.fork({ name: 'fooZone', onScheduleTask: function(delegate, curr, target, task) { log('Zone begin to schedule task not async yet ' + task.source); return delegate.scheduleTask(target, task); }, onInvokeTask: function(delegate, curr, target, task, applyThis, applyArgs) { log('~~~~Zone before invoke async callback~~~~' + task.source); delegate.invokeTask(target, task, applyThis, applyArgs); log('~~~~Zone after invoke async callback~~~~' + task.source); }, }).run(function() { log('current zone, ' + Zone.current.name); setTimeout(function() { log('timeout is up, ', Zone.current.name); }, 100); }); }; foo(); 

并在nodejs中运行后,输出将是。

 current zone, fooZone Zone begin to schedule task not async yetsetTimeout ~~~~Zone before invoke async callback~~~~setTimeout timeout is up, ~~~~Zone after invoke async callback~~~~setTimeout 

我遇到了同样的问题。 如果你像我一样,你可能看到zone.js回购这样的例子之一 ,看到之前的Tasks和afterTask挂钩。 但是,如果您查看API并查看ZoneSpec接口(指定zone.fork将识别的钩子),则不会提到beforeTask或afterTask任何地方。 这很可能是因为钩子已经被重写/重构了,因为这个示例被写入并且没有被更新

但是,在名为“onInvokeTask”的API中提到的钩子定义为:

 onInvokeTask?: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task, applyThis: any, applyArgs: any) => any; 

这将被调用,而不是在ZoneSpec中调用的任务,所以我尝试了这样的事情:

 require('zone.js'); function foo () { Zone.current.fork({ name: 'foo_zone', onInvokeTask: function (parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) { console.log('~~~ ZONE START ~~~'); parentZoneDelegate.invokeTask(targetZone, task); console.log('~~~ ZONE END ~~~'); }, }) .run(function () { setTimeout(function() { console.log('in the zone'); console.log('Zone.current.name', Zone.current.name); // prints foo_zone setTimeout(() => { console.log('timeout is up'); }, 1000); }, 0); }); } foo(); 

打印所需的结果:

 ~~~ ZONE START ~~~ in the zone Zone.current.name foo_zone ~~~ ZONE END ~~~ ~~~ ZONE START ~~~ timeout is up ~~~ ZONE END ~~~ 

有几件事要注意:

  1. 与示例中的beforeTask和afterTask不同,在任务运行前后,调用onInvokeTask钩子代替运行任务,因此如果需要任务,必须指定在该钩子中运行任务运行,因此parentZoneDelegate.invokeTask(targetZone, task);

  2. 我在setTimeout(function() { ... }, 0)的run函数内部封装了代码setTimeout(function() { ... }, 0)因为run函数中的代码实际上与您示例中的所有代码在相同的任务中被调用(除了代码在新任务中运行的setTimeout调用)和onInvokeTask挂钩不适用于当前任务,因为当前任务已经被调用。 这意味着~~~ ZONE START ~~~~~~ ZONE END ~~~只会在周围打印timeout is up