我正在试图弄清楚fakeAsync的tick()方法与done()的区别,正如堆栈溢出上的某些
answers所建议的那样.
使用tick()我们可以模拟超时,但我们可以使用done()完成相同的操作吗?
为什么angular将它视为使用异步或伪同步?
举个例子.
这个方法对我有用……
it("Should display names",(done:any) => { component.names = [ { "firstname": "abc","lastname": "max" },{ "firstname": "def",]; done(); fixture.detectChanges(); let wrapBox = fixture.debugElement.queryAll(By.css('.wrapBox')); console.log(wrapBox); });
但是以下方法返回’6个计时器仍在队列中’错误…
it("Should display names",fakeAsync(() => { component.names = [ { "firstname": "abc",]; tick(); fixture.detectChanges(); let wrapBox = fixture.debugElement.queryAll(By.css('.wrapBox')); console.log(wrapBox); }));
注意:
>数组名称的数据是异步的,因为它是使用“get”操作从后端检索的.但在这里我嘲笑数据.
>迭代数组中的数据并传递给另一个子组件,该子组件在视图中显示它.
解决方法
这两件事没有任何共同之处.
完成只是一个回调,让你的测试运行器知道异步操作何时完成.
例如:
it('should wait for this promise to finish',done => { const p = new Promise((resolve,reject) => setTimeout(() => resolve(`I'm the promise result`),1000) ); p.then(result => { // following will display "I'm the promise result" after 1s console.log(result); // this let your test runner know that it can move forward // because we're done here // the test will take 1s due to the setTimeout at 1000ms done(); }); });
您也可以使用异步(只是为了避免手动调用):
it( 'should wait for this promise to finish',async(() => { const p = new Promise((resolve,reject) => setTimeout(() => resolve(`I'm the promise result`),1000) ); p.then(result => // following will display "I'm the promise result" after 1s console.log(result) ); // notice that we didn't call `done` here thanks to async // which created a special zone from zone.js // this test is now aware of pending async operation and will wait // for it before passing to the next one }) );
现在,fakeAsync可以让你随着时间的推移控制(这真的很强大),所以你可以用同步方式编写测试,并模拟时间过去以避免等待setTimeout,例如:
it( 'should wait for this promise to finish',fakeAsync(() => { const p = new Promise((resolve,1000) ); // simulates time moving forward and executing async tasks flush(); p.then(result => // following will display "I'm the promise result" **instantly** console.log(result) ); // notice that we didn't call `done` here has there's no async task pending }) );
所以要清楚一点,在上一个例子中使用fakeAsync,如果setTimeout设置为10s,测试仍然会立即执行.