tick()
和flush()
。这两者似乎都做类似的事情。从角度文档来看,它表示勾选:
模拟 fakeAsync 区域中计时器的异步时间流逝。
冲洗:
通过清空宏任务队列直至其为空来模拟 fakeAsync 区域中计时器的异步时间流逝。返回的值是已经过去的时间的毫秒数。
谁能给我解释一下其中的区别吗?
编辑(在评论中回答):
此外,在 Angular 文档中
tick()
是不带参数使用的,该行的注释甚至使用了短语“flush”
it('should display error when TwainService fails', fakeAsync(() => {
// tell spy to return an error observable
getQuoteSpy.and.returnValue(
throwError('TwainService test failure'));
fixture.detectChanges(); // onInit()
// sync spy errors immediately after init
tick(); // flush the component's setTimeout()
fixture.detectChanges(); // update errorMessage within setTimeout()
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
相对于“之前启动的”异步操作,它们执行不同的操作。例如;调用 setTimeout(...)
启动异步操作。
tick()
时间。
flush()
time移至末尾。
勾选
的方式向前移动时间,直到所有 10 计时器完成。 Tick 被调用多次。
https://github.com/angular/angular/blob/master/packages/core/test/fake_async_spec.ts#L205
it('should clear periodic timers', fakeAsync(() => {
let cycles = 0;
const id = setInterval(() => { cycles++; }, 10);
tick(10);
expect(cycles).toEqual(1);
discardPeriodicTasks();
// Tick once to clear out the timer which already started.
tick(10);
expect(cycles).toEqual(2);
tick(10);
// Nothing should change
expect(cycles).toEqual(2);
}));
冲洗
it('should flush multiple tasks', fakeAsync(() => {
let ran = false;
let ran2 = false;
setTimeout(() => { ran = true; }, 10);
setTimeout(() => { ran2 = true; }, 30);
let elapsed = flush();
expect(ran).toEqual(true);
expect(ran2).toEqual(true);
expect(elapsed).toEqual(30);
}));
和 flush 调用 Zone.js 的 FakeAsyncTestZoneSpec。
tick
flush
首先刷新所有微任务,例如
Promise.then
和 queueMicrotask
。tick
默认刻度计数为 0,由 Angular 定义,以毫秒为单位。它执行宏任务,包括周期性任务,例如
setInterval
、计划到当前时间加上滴答计数。 因此,默认情况下
tick
flush
默认轮数为 20,由 Zone.js 假异步测试调度程序定义。它执行宏任务,但不执行周期性任务,直到任务的轮数(被视为限制)或第一个周期性任务。 因此,默认情况下
flush
flush
以获取完整的示例测试集。
it('tick executes all microtasks and macrotasks', fakeAsync(() => {
const spy = jasmine.createSpy('interval');
zone.runTask(() => queueMicrotask(() => { }));
zone.runTask(() => setInterval(spy, 1));
zone.runTask(() => queueMicrotask(() => { }));
expect(zone.hasPendingMicrotasks).toBeTrue();
expect(zone.hasPendingMacrotasks).toBeTrue();
tick(1);
expect(zone.hasPendingMicrotasks).toBeFalse();
expect(zone.hasPendingMacrotasks).toBeTrue();
expect(spy).toHaveBeenCalledOnceWith();
discardPeriodicTasks();
}));
it('flush executes all microtasks and non-periodic macrotasks', fakeAsync(() => {
const spy = jasmine.createSpy('interval');
zone.runTask(() => queueMicrotask(() => { }));
zone.runTask(() => setTimeout(spy));
zone.runTask(() => queueMicrotask(() => { }));
expect(zone.hasPendingMicrotasks).toBeTrue();
expect(zone.hasPendingMacrotasks).toBeTrue();
flush();
expect(zone.hasPendingMicrotasks).toBeFalse();
expect(spy).toHaveBeenCalledOnceWith();
}));