我尝试在节点中使用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();

现在在区域内,所有内容都打印正常,包括区域名称,但不会调用任何钩子。
我是否遗漏了zone.js + node.js的基本内容?
(与节点v5.0.0一起运行,zone.js 0.6.23)
答案 0 :(得分:1)
以下是示例存储库。 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
答案 1 :(得分:0)
我遇到了同样的问题。如果你像我一样,你可能会看到像this one这样的zone.js repo中的一个例子,并且看到了使用挂钩beforeTask和afterTask。但是,如果查看API并查看ZoneSpec接口(指定zone.fork将识别的挂钩),则不会在任何地方提及beforeTask或afterTask。这很可能是因为自编写示例的时间以来钩子已被重命名/重构,并且它还没有更新
但是,API中提到了一个名为" onInvokeTask"定义为:
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函数中,因为run函数中的代码实际上是在与示例中的所有代码相同的任务中调用的(setTimeout中的代码除外)调用在新任务中运行)并且onInvokeTask挂钩不适用于当前任务,因为已经调用了当前任务。这意味着~~~ ZONE START ~~~
和~~~ ZONE END ~~~
只会打印在timeout is up
行周围。