在节点中使用zone.js钩子
我正在尝试在节点中使用angular / zone.js编写一个简单演示,但由于某种原因, beforeTask
或afterTask
都不会被调用。
这是我正在运行的代码:
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 ~~~
有几件事要注意:
-
与示例中的beforeTask和afterTask不同,在任务运行前后,调用onInvokeTask钩子代替运行任务,因此如果需要任务,必须指定在该钩子中运行任务运行,因此
parentZoneDelegate.invokeTask(targetZone, task);
-
我在
setTimeout(function() { ... }, 0)
的run函数内部封装了代码setTimeout(function() { ... }, 0)
因为run函数中的代码实际上与您示例中的所有代码在相同的任务中被调用(除了代码在新任务中运行的setTimeout调用)和onInvokeTask挂钩不适用于当前任务,因为当前任务已经被调用。 这意味着~~~ ZONE START ~~~
和~~~ ZONE END ~~~
只会在周围打印timeout is up
。