网站搜索

javascript - forkJoin 内的日志行没有被调用


我有一个方法。

private getData() {
     console.log('Begin');
     const sub1 = this.http['url1'].get();
     const sub2 = this.http['url2'].get();
     const sub3 = this.http['url3'].get();
     const sub = forkJoin([sub1, sub2, sub3]).subscribe(([res1, res2, res3]) => {
         console.log('fork join');
         this.list1 = res1 as ProjectDto[];
         this.list2 = res2 as Array<MyTest>;
         this.list3 = res3 as Array<MyTest>;
         sessionStorage.setItem('a', JSON.stringify(this.list1));
         sessionStorage.setItem('b', JSON.stringify(this.list2));
         sessionStorage.setItem('c', JSON.stringify(this.list3));
         console.log('set items');
     });
     console.log('Completed');
   }

方法被调用了。然而在 forkJoin 内的两行日志根本没有被调用。所以我不知道是否成功从服务获取了数据。我使用的是 rxjs 5.5.6。

更新:

我的错,我刚发现它们实际上是被打印出来的,因为服务花了很长时间。所以问题变成了如何同步打印日志。现在它们先打印Begin和Completed。

答案#1

subscribe 的第三个参数将接受一个回调,并在流完成时被调用

 const sub = forkJoin([sub1, sub2, sub3]).subscribe(([res1, res2, res3]) => {
     console.log('fork join');
     this.list1 = res1 as ProjectDto[];
     this.list2 = res2 as Array<MyTest>;
     this.list3 = res3 as Array<MyTest>;
     sessionStorage.setItem('a', JSON.stringify(this.list1));
     sessionStorage.setItem('b', JSON.stringify(this.list2));
     sessionStorage.setItem('c', JSON.stringify(this.list3));
 },null,()=>console.log('complete'));

答案#2

你应该将 console.log('Completed'); 放在 subscribe 内,因为 subscribe 是 异步的,并且会在稍后的时间发生。

但如果你想保持结构不变,你可以像编程一样使用 promise。

import { take } from 'rxjs/operators';
....
private async getData(): Promise<boolean> {
     console.log('Begin');
     const sub1 = this.http['url1'].get();
     const sub2 = this.http['url2'].get();
     const sub3 = this.http['url3'].get();
     const [res1, res2, res3] = await forkJoin([sub1, sub2, sub3]).pipe(take(1)).toPromise();
     console.log('fork join');
     this.list1 = res1 as ProjectDto[];
     this.list2 = res2 as Array<MyTest>;
     this.list3 = res3 as Array<MyTest>;
     sessionStorage.setItem('a', JSON.stringify(this.list1));
     sessionStorage.setItem('b', JSON.stringify(this.list2));
     sessionStorage.setItem('c', JSON.stringify(this.list3));
     console.log('set items');
     console.log('Completed');
     return Promise.resolve(true);
   }