什么时候使用 zone.run()?
When to use zone.run()?
我试图在 angular 中阅读很多关于 NgZone
的内容。我知道 angular 使用 zone.js
进行变化检测。我看到一些代码使用了 zone.run 并在其中放置了一些操作。
它实际上是做什么的?
还是想不通zone.run
的实际用途
this.zone.run(() => {
/* my code here */
});
借助这个link,我明白了一些。
答案本身在您提到的博客中提供。我会尝试进一步分解它。在 given example 中:
Situation: You are creating a progress-bar
component whose value will be updated every 10 milli seconds
没有NgZone
:
单击 button
后,将使用函数调用 increaseProgress()
(进度条完成后将显示其值)
<button (click)="processWithinAngularZone()">
Process within Angular zone
</button>
它每 10 毫秒调用一次,并不断增加 this.progress
计数器直到 100
increaseProgress(doneCallback: () => void) {
this.progress += 1;
console.log(`Current progress: ${this.progress}%`);
if (this.progress < 100) {
window.setTimeout(() => {
this.increaseProgress(doneCallback);
}, 10);
} else {
doneCallback();
}
}
这会起作用,但是 因为我们使用的是 setTimeout
,ChangeDetection
周期将每隔 10 milliseconds
触发一次,这将影响性能申请
与NgZone
:
ngZone
我们正在通过,zone.run()
而不是 console.log
。一旦计数器完成,这基本上将作为 ChangeDetection
的触发器。
现在,为了避免 setTimeout
的 效果(由于猴子修补而触发 ChangeDetection
),我们将整个执行块包装在 this.zone.runOutsideAngular
。 ChangeDetection
仅在我们显式调用 zone.run()
.
时调用
this.zone.runOutsideAngular(() => {
this.increaseProgress(() => {
this.zone.run(() => {
console.log('Outside Done!');
});
});
});
类似用例:
假设您需要在 scrollEvent
上实现一些逻辑,这可能会触发一个可能导致触发 ChangeDetection
的函数。为避免这种情况,我们可以使用 zone.runOutsideAngular
并在某些 action/duration 之后使用 zone.run()
.
手动触发 ChangeDetection
您正在使用一些第 3 方库(它在 Angular ChangeDetection
之外工作)并且您需要在第 3 个事件发生后手动触发 CD
派对图书馆。
它不是很频繁地使用它,但是,是的,它会在不为人知的情况下产生不需要的行为。
我希望它能帮助您更好地理解这个概念
我试图在 angular 中阅读很多关于 NgZone
的内容。我知道 angular 使用 zone.js
进行变化检测。我看到一些代码使用了 zone.run 并在其中放置了一些操作。
它实际上是做什么的?
还是想不通zone.run
this.zone.run(() => {
/* my code here */
});
借助这个link,我明白了一些。
答案本身在您提到的博客中提供。我会尝试进一步分解它。在 given example 中:
Situation: You are creating a
progress-bar
component whose value will be updated every 10 milli seconds
没有NgZone
:
单击 button
后,将使用函数调用 increaseProgress()
(进度条完成后将显示其值)
<button (click)="processWithinAngularZone()">
Process within Angular zone
</button>
它每 10 毫秒调用一次,并不断增加 this.progress
计数器直到 100
increaseProgress(doneCallback: () => void) {
this.progress += 1;
console.log(`Current progress: ${this.progress}%`);
if (this.progress < 100) {
window.setTimeout(() => {
this.increaseProgress(doneCallback);
}, 10);
} else {
doneCallback();
}
}
这会起作用,但是 因为我们使用的是 setTimeout
,ChangeDetection
周期将每隔 10 milliseconds
触发一次,这将影响性能申请
与NgZone
:
ngZone
我们正在通过,zone.run()
而不是 console.log
。一旦计数器完成,这基本上将作为 ChangeDetection
的触发器。
现在,为了避免 setTimeout
的 效果(由于猴子修补而触发 ChangeDetection
),我们将整个执行块包装在 this.zone.runOutsideAngular
。 ChangeDetection
仅在我们显式调用 zone.run()
.
this.zone.runOutsideAngular(() => {
this.increaseProgress(() => {
this.zone.run(() => {
console.log('Outside Done!');
});
});
});
类似用例:
假设您需要在
手动触发scrollEvent
上实现一些逻辑,这可能会触发一个可能导致触发ChangeDetection
的函数。为避免这种情况,我们可以使用zone.runOutsideAngular
并在某些 action/duration 之后使用zone.run()
.ChangeDetection
您正在使用一些第 3 方库(它在 Angular
ChangeDetection
之外工作)并且您需要在第 3 个事件发生后手动触发CD
派对图书馆。
它不是很频繁地使用它,但是,是的,它会在不为人知的情况下产生不需要的行为。
我希望它能帮助您更好地理解这个概念