我有一个用例,我需要进行两次异步调用。顺序在这里很重要。在开始下一个呼叫之前,第一个呼叫需要完成(或失败)。
我在下面有一个示例代码显示了我需要什么,但它不是以反应方式完成的(即使用 rxjs 运算符)
public performDBTasks(): Observable<void> {
return Observable.create(
(observer)=> {
this.performDBTask1().subscribe(
()=> {
this.performDBTask2().subscribe(
()=> {
observer.next();
observer.complete();
},
()=> {
observer.error();
});
},
(error)=> {
this.performDBTask2().subscribe(
()=> {
observer.next();
observer.complete();
},
()=> {
observer.error();
});
});
});
}
您可以使用 switchMap 和 last 来解决您的问题。
const { Subject, merge, of} = rxjs;
const { switchMap, last, map, catchError } = rxjs.operators;
const first$ = new Subject();
const second$ = new Subject();
const result$ = first$.pipe(
// catch an error and return an observable that gets "?" and completes afterwards
catchError(() => of("?")),
// only emit if observable completes and return last value
last(),
// switch to observable second$
switchMap((firstValue) =>
second$.pipe(
// just for logging purpose - log the first$ and second$ value
map((secondValue) => [firstValue, secondValue])
)
)
);
result$.subscribe(console.log);
first$.next(1);
first$.next(2);
first$.complete();
second$.next(4);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>
信息
first$.error("msg")
创建错误。相应的 stackoverflow 问题:如何在行为主题上抛出错误并继续流。随意模拟管道上的错误。不需要模拟来回答问题,所以我将避免实施模拟。您可以将
from
与 concatMap
一起使用,它会一直等到上一个请求完成。
const { from, concatMap, fetch: { fromFetch }, tap } = rxjs;
const endpoints = [
// Returns 404
'https://dummy.restapiexample.com/api/v1/404-error',
// Returns 200
'https://dummy.restapiexample.com/api/v1/employee/1'
];
from(endpoints).pipe(
// Won't fetch until the previous request has finished.
concatMap(url => fromFetch(url).pipe(
tap(url => console.log(`Making request to: ${url.url}`)),
)),
tap(resp => console.log(resp.status))
).subscribe()
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.0/rxjs.umd.min.js"></script>