import { Component } from "@angular/core";
import { Observable, of, throwError, Subscription, forkJoin } from "rxjs";
import { mergeMap, map, delay, timeout, first, take } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
class Test {
id: number;
firstObj: FirstObj;
secondObj: SecondObj;
thirdObj: string;
}
interface FirstObj {
firstObs: boolean;
result: string;
}
interface SecondObj {
secondObs1: boolean;
secondObs2: boolean;
}
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
private workOrderSubscription: Subscription;
name = "Angular";
obsOne: Observable<any> = of("First Obs")
.pipe(delay(6000))
.pipe(
map(res => {
return {
firstObs: true,
result: res
};
})
);
dataTwo: SecondObj = { secondObs1: true, secondObs2: false };
obsTwo: Observable<any> = of(this.dataTwo);
obsThree: Observable<any> = of("error");
private getId(): Observable<any> {
return of("id" as string);
}
public retrieveWork(): Observable<Test> {
const test: Test = new Test();
this.getId().subscribe((id: number) => {
test.id = id as number;
forkJoin(this.obsOne, this.obsTwo, this.obsThree).subscribe(
([first, second, third]: [FirstObj, SecondObj, string]) => {
// some appropriate checks here
test.firstObj = first as FirstObj;
test.secondObj = second as SecondObj;
test.thirdObj = third as string;
console.log("first is " + first.result);
console.log("second is " + second.secondObs1);
console.log("third is " + third);
console.log(`inside ******************** ${JSON.stringify(test)}`);
return of(test);
},
error => {
//error here
console.log("GOT ERROR");
}
);
});
console.log(`returning ******************** ${JSON.stringify(test)}`);
return of(test);
}
ngOnInit() {
console.log("data ************************");
this.retrieveWork()
.pipe(timeout(10000))
.subscribe(data => {
{
console.log("printing data ***************************");
console.log(`${JSON.stringify(data)}`);
}
});
}
ngOnDestroy() {}
}
我尝试了很多方法,基本上我想做的是在ngOnInit
中,我正在订阅get(),但是我得到的数据并不完整。订阅不会等到forkJoin
完全返回。我不确定如何获取完整的数据。
在完成第一个订阅后,我希望第一个订阅和第二个订阅都完成,然后填充“ Test”类,然后在ngOnInit
中填充我的订阅者以获取数据。
我的输出看起来像这样
数据************************
返回******************** {“ id”:“ id”}
打印数据***************************
{“ id”:“ id”}
首先是初次观察
秒是正确的
第三个是错误
inside ******************** {“ id”:“ id”,“ firstObj”:{“ firstObs”:true,“ result”:“ First Obs“},” secondObj“:{” secondObs1“:true,” secondObs2“:false},” thirdObj“:”错误“}
正如我们在上面的输出中看到的那样,只有id被打印出来(第一次订阅后),
但是在第二次订阅之后,ngOnInit
中的订阅者不再获取数据。
谢谢。
答案 0 :(得分:1)
我将嵌套的Observable替换为高阶映射运算符(switchMap),它似乎可以正常工作。 (但是我不清楚应该输出什么。)
这就是我所拥有的:
opts
这能达到您的期望吗?
答案 1 :(得分:0)
最后,这似乎可行。我是RXJS的新手。欢迎任何建议。
还处理了所有错误情况。
import { Component } from "@angular/core";
import {
Observable,
of,
throwError,
Subscription,
forkJoin,
combineLatest
} from "rxjs";
import {
mergeMap,
map,
delay,
timeout,
first,
take,
catchError
} from "rxjs/operators";
import { ajax } from "rxjs/ajax";
class Test {
id: number;
firstObj: FirstObj;
secondObj: SecondObj;
}
interface FirstObj {
firstObs: boolean;
result: string;
}
interface SecondObj {
secondObs1: boolean;
secondObs2: boolean;
}
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
private workOrderSubscription: Subscription;
name = "Angular";
dataone: FirstObj = { firstObs: true, result: "hai" };
obsOne: Observable<any> = of(this.dataone).pipe(delay(1000));
dataTwo: SecondObj = { secondObs1: true, secondObs2: false };
obsTwo: Observable<any> = throwError(this.dataTwo);
private getId(): Observable<any> {
return of(1).pipe(delay(4000));
}
public get(): Observable<any> {
let test: Test = new Test();
return new Observable(subscriber =>
this.getId().pipe(timeout(5000)).subscribe(
(id: number) => {
test.id = id;
forkJoin(
this.obsOne.pipe(timeout(1000)).pipe(catchError(error => of(null))),
this.obsTwo.pipe(timeout(1000)).pipe(catchError(error => of(null))),
).subscribe(([first, second]) => {
test.firstObj = first;
test.secondObj = second;
console.log("printing data ***************************2");
console.log(`${JSON.stringify(test)}`);
subscriber.next(test);
subscriber.complete();
});
},
err => {
console.log("error while getting data");
subscriber.error("error while getting data");
subscriber.unsubscribe();
}
)
);
}
ngOnInit() {
let subscription: Subscription = this.get()
.pipe(timeout(6000))
.subscribe(
(data: Test) => {
console.log("in subscribe");
console.log(`${JSON.stringify(data)}`);
},
err => {
console.log("ERROR " + err);
subscription.unsubscribe();
}
);
}
ngOnDestroy() {}
}