我遇到了同样的问题。如果您像我一样,您可能会在 zone.js 存储库中看到一个像这样的示例,并看到使用了 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);
我将代码包装在 run 函数中,setTimeout(function() { ... }, 0)
因为 run 函数中的代码实际上是在与示例中的所有代码相同的任务中调用的(除了在新任务中运行的 setTimeout 调用中的代码)和onInvokeTask 钩子不适用于当前任务,因为当前任务已经被调用。这意味着~~~ ZONE START ~~~
并且~~~ ZONE END ~~~
只会timeout is up
在行周围打印。