RxJS订阅如何实现finally/complete代码块?及first()订阅疑问
问题解答
为什么complete回调不触发?
Observable的通知规则是error和complete是互斥的:如果流发出了error通知,就不会再触发complete回调;只有当流正常完成(没有出错)时,complete才会执行。所以你的代码里,请求失败时只会触发error回调,complete里的启用按钮逻辑根本不会运行。
共享逻辑的实现方式
不用重复写代码,推荐用RxJS的finalize操作符,它会在Observable无论正常完成还是出错终止时都执行回调,完美适配你这种“不管成功失败都要做的操作”。
修改后的代码示例:
this.buttonDisabled = true; this.client.post(this.formGroup.value).pipe( first(), finalize(() => { this.buttonDisabled = false; }) // 放在这里,成功失败都会执行 ).subscribe( () => this.dismissModal(), // 成功时关闭模态框 (error) => this.setError(error) // 失败时显示错误 );
另外还有一种方式是利用订阅的add方法,它会在订阅终止时执行回调(无论正常还是出错),但finalize的可读性更好,更推荐前者:
this.buttonDisabled = true; const subscription = this.client.post(this.formGroup.value).pipe( first() ).subscribe( () => this.dismissModal(), (error) => this.setError(error) ); subscription.add(() => { this.buttonDisabled = false; });
关于first()是否需要手动取消订阅?
是的,不需要手动取消订阅。first()操作符的作用就是:当Observable发出第一个值后,自动完成流并取消订阅;如果流中途出错,也会立即终止流并清理订阅。所以无论是请求成功还是失败,first()都会帮你自动处理订阅的取消,不用担心内存泄漏问题。
内容的提问来源于stack exchange,提问作者patrick
相关产品推荐
相关产品推荐

