离子 - 角度 2 - 订阅 http.post 响应



我有一些代码要和你分享。它来自Ionic 2项目。我认为我的做法很糟糕,所以我想正确地重构它。

我正在将 base64 中的图像发送到 API,API 将图像保存为服务器上的.png,然后在 API 服务器上向我发送回包含此图像 URL 的响应。该应用程序在等待 API 响应时会显示加载屏幕,因此您无法同时进行多个调用。此外,API 为每个调用回复 1 个响应,仅此而已。

这是一个简单的调用:

api.service.ts

private _imgUrl = new Subject<string>();
public getImgUrl(imgURI: any): Observable<string> {
  this.apiImgUrl(imgURI);
  return this._imgUrl.asObservable();
}
private setImgUrl(url: any) {
  this._imgUrl.next(url);
}
private apiImgUrl(imgURI: string) {
  var data  = {
    src: imgURI
  };
  var postData = JSON.stringify(data);
  var headers = new Headers({ 'Content-Type': 'application/json' });
  var options = new RequestOptions({ headers: headers });
  this.http.post(
      'my-api-url.com', 
      postData, 
      options
    )
    .retry(3)
    .toPromise()
      .then((res) => {
        var body = res.json();
        this.setImgUrl(body);
      })
      .catch(this.handleErrorPromise);
}  

my-module.ts

import { ApiService }   from '../shared';
...
private socialImageSubscription: Subscription;
private i = 0;
constructor(private _api: ApiService) {}
private getImageFromAPI(canvasURI) {
  this.socialImageSubscription = this._api.getImgUrl(canvasURI).subscribe((res:any) => {
     this.i++;
     console.log(this.i, 'socialImageSubscription', res.data);
    // doing something with the response
  });
}

现在,getImageFromAPI()是由(click)触发的。因此,如果我单击一次,我会得到以下控制台日志:

1,"socialImageSubscription", www.apidomain.com/url1

第二次点击时:

2,"socialImageSubscription", www.apidomain.com/url2
3,"socialImageSubscription", www.apidomain.com/url2

第三次点击时:

 4,"socialImageSubscription", www.apidomain.com/url3
 5,"socialImageSubscription", www.apidomain.com/url3
 6,"socialImageSubscription", www.apidomain.com/url4

因此,每次我访问getImageFromAPI()时,它都会创建一个新订阅,而以前的订阅保持活动状态。

如何正确编写此代码?

试试这个: 它应该可以解决您的问题。

private getImageFromAPI(canvasURI) {
this._api.getImgUrl(canvasURI).subscribe((res:any) => {
         this.i++;
         console.log(this.i, 'socialImageSubscription', res.data);
        // doing something with the response
      }).unsubscribe();           // unsubscribe here
}

立即取消订阅,这样您就不会激活订阅。而且您在这里也不需要订阅变量。

玩了一会儿,找到了我要找的东西:

api.service.ts

private apiImgUrl(imgURI: string) {
  var data  = {
    src: imgURI
  };
  var postData = JSON.stringify(data);
  var headers = new Headers({ 'Content-Type': 'application/json' });
  var options = new RequestOptions({ headers: headers });
  return this.http.post(
      'my-api-url.com', 
      postData, 
      options
    )
    .retry(3)
    .toPromise()
      .then((res) => {
        var body = res.json();
        return body;
      })
      .catch(this.handleErrorPromise);
}  

my-module.ts

import { ApiService }   from '../shared';
...
private i = 0;
constructor(private _api: ApiService) {}
private getImageFromAPI(canvasURI) {
  this._api.apiImgUrl(canvasURI).then((res:any) => {
     this.i++;
     console.log(this.i, 'socialImageSubscription', res.data);
    // doing something with the response
  });
}

该代码更易于阅读,并删除了无用的订阅。控制台日志是您所期望的。第一次点击:

1,"socialImageSubscription", www.apidomain.com/url1

第二次点击时:

2,"socialImageSubscription", www.apidomain.com/url2

第三次点击时:

 3,"socialImageSubscription", www.apidomain.com/url3

相关内容

  • 没有找到相关文章

最新更新