之前一直以为complete就是完成之后不论成不成功都会进入,就和try catch 里面的finally一样,直到今天,我写在complete里面的代码,在进入error之后没进入,才发现。去查了下总结下。
finalize和complete都是用于处理可观察对象结束时的操作符,但是它们有一些区别:
- finalize是一个管道操作符,它需要在subscribe之前使用pipe方法来应用于可观察对象。finalize接受一个函数作为参数,这个函数会在可观察对象被取消订阅时执行,无论是因为成功、错误还是主动取消订阅。
- complete是一个订阅回调函数,它需要在subscribe方法中作为第三个参数传入。complete只有在可观察对象成功完成时才会执行,如果发生错误或者主动取消订阅,complete不会执行。
import { interval, finalize, tap, noop, timer } from 'rxjs';
const source = interval(100).pipe(
finalize( () => console.log(' [finalize] Called')),
tap( {
next: () => console.log(' [next] Called'),
error: () => console.log(' [error] Not called'),
complete: () => console.log(' [tap complete] Not called')
})
);
const sub = source.subscribe(
x => console.log(x),
noop,
() => console.log(' [complete] Not called')
);
timer(150).subscribe(
() => sub.unsubscribe()
);
运行的结果是:
[next] Called
0
[next] Called
1
[finalize] Called
可以看到,finalize在取消订阅时被调用了,而complete没有被调用。如果想要在可观察对象结束时无论如何都执行一些操作,应该使用finalize操作符。如果只想要在可观察对象成功完成时执行一些操作,应该使用complete回调函数。
关于其中的noop函数,可以看我另一篇blog:
https://blog.csdn.net/Damien_J_Scott/article/details/132692290