如何在Observer中检测订阅取消?封装HTTP请求Observable后无法检测
如何在自定义Observable中检测订阅取消
你遇到的问题核心是:在Observable.create的回调里,你没有处理订阅取消时的清理逻辑。当外部调用subscription.unsubscribe()时,你的内部HTTP请求订阅不会自动终止,而且你也没法感知到这个取消动作。
解决方案:利用Observable.create的清理函数
Observable.create的回调函数可以返回一个清理函数,当订阅被取消(调用unsubscribe)、Observable完成或报错时,这个函数会自动执行。你可以在这里取消内部的HTTP订阅,同时添加订阅取消的检测逻辑。
修改后的代码如下:
constructor( @Inject(Http) private http: Http) { } ... const observable = Observable.create((observer: Observer<any>) => { // 保存内部HTTP请求的订阅实例 const httpSubscription = this.http.post(url, body) .subscribe((p) => { observer.next(p.json()); observer.complete(); }, (err) => { observer.error(err); observer.complete(); }); // 返回清理函数:订阅取消时会触发这个函数 return () => { // 这里就是检测到订阅取消的地方,可以添加你的自定义逻辑 console.log("订阅已被取消!"); // 取消内部的HTTP请求订阅,避免不必要的网络请求 httpSubscription.unsubscribe(); }; }); const subscription = observable.subscribe((r) => { alert("result : "+r); }, (err) => { alert("error occure..."); }); // 测试取消订阅:调用后会触发清理函数里的逻辑 // subscription.unsubscribe();
更简洁的替代方案(推荐)
其实你完全不需要用Observable.create来包裹HTTP请求——因为Angular的Http.post本身就返回一个Observable。你可以直接对它做数据转换,这样取消订阅时会自动终止HTTP请求,代码更简洁:
const observable = this.http.post(url, body) .map(response => response.json()); // 直接转换响应数据 const subscription = observable.subscribe((r) => { alert("result : "+r); }, (err) => { alert("error occure..."); });
这样当你调用subscription.unsubscribe()时,HTTP请求会被自动取消,不需要手动处理清理逻辑。
内容的提问来源于stack exchange,提问作者Dániel Kis
相关产品推荐
相关产品推荐

