- Task Scheduling
Task Scheduling
To track tasks, we have to revisit how setTimeout() is monkey patched to modify the way Zone’s are tracked.
要跟踪任务,我们必须看下 setTimeout() 的猴子补丁如何修改被跟踪的 zone。
// 保存setTimeout的原始引用let originalSetTimeout = window.setTimeout;// 使用在 zone 中包含回调的函数覆盖API。window.setTimeout = function(callback, delay) {// 对当前 zone 使用scheduleTask API。Zone.current.scheduleMacroTask(// 调试信息'setTimeout',// 回调需要在当前 zone 执行。callback,// 可选数据,如任务是否重复。null,// 默认计划行为(task) => {return originalSetTimeout(// Use the task invoke method, so that the task can// call callback in the correct zone.task.invoke,// original delay informationdelay);});}
使用示例:
// Create a logging zonelet logZone = Zone.current.fork({onScheduleTask: function(parentZoneDelegate, currentZone,targetZone, task) {// Print when async tasks are scheduledconsole.log('Schedule', task.source);return parentZoneDelegate.scheduleTask(targetZone, task);},onInvokeTask: function(parentZoneDelegate, currentZone,targetZone, task, applyThis, applyArgs) {// Print when async tasks are invokedconsole.log('Invoke', task.source);return parentZoneDelegate.invokeTask(targetZone, applyThis, applyArgs);}});console.log('start');logZone.run(() => {setTimeout(() => null, 0);});console.log('end');
输出结果
startSchedule setTimeoutendInvoke setTimeout
关键点:
- All APIs which schedule tasks use Zone.prototype.scheduleTask() instead of Zone.prototype.wrap().
- Tasks use Zone.prototype.runGuarded() for callback execution, hence they handle all of the errors.
- Tasks are intercepted using invokeTask() whereas zones are intercepted using invoke().
