Ngrx Component Store Effect报错后无法再次触发求助
问题分析与解决方案
问题根源
你的deleteProduct$ Effect报错后订阅关闭,核心原因有两点:
tapResponse的错误回调仅处理错误但不会捕获错误,错误会继续向下传递到外层的catchError;catchError返回了EMPTY,这是一个立即完成的Observable,会导致整个Effect流直接终止,后续触发自然无响应。
修正方案
将错误捕获逻辑移到switchMap内部,确保每个删除请求的错误仅终止当前子流,不会影响外层接收新触发的流;同时避免返回EMPTY,改用不会终止流的安全Observable。
修正后的代码
readonly deleteProduct$ = this.effect( (productID$: Observable<string>): Observable<PostgrestResponse<Product> | null> => { return productID$.pipe( switchMap((productID) => // 把错误捕获放在switchMap内部,每个请求错误独立处理 this._supabaseService.delete<Product>(productsPath, 'id', productID).pipe( tapResponse( // 成功回调:仅处理请求成功的场景 ({ data: products, error }) => { this.patchState({ loading: false, error }); if (!error) { this.deleteProduct(products[0]?.id); this.toastSuccessMessage('Deleted Successfully!'); } else { this.handleError(error); } }, // 错误回调:处理请求抛出的异常 (error: Error) => { this.patchState({ loading: false, error }); this.handleError(error); } ), // 捕获当前请求错误,返回null避免子流终止外层流 catchError(() => of(null)) ) ) ); } );
关键说明
- 错误捕获的位置:将
catchError放在switchMap内部,每个删除请求的错误只会终止当前的子请求流,外层的productID$流依然能接收新的触发信号; - 避免流终止:用
of(null)替代EMPTY,确保子流错误处理后正常完成,不会导致整个Effect流终止; - 修正逻辑分支:在
tapResponse的成功回调中区分业务错误和正常成功场景,避免混淆Supabase响应的error字段与Observable抛出的异常。
内容的提问来源于stack exchange,提问作者Balaji Balamurugan
相关产品推荐
相关产品推荐

