簡體   English   中英

從 Angular 服務和組件中的 observable 返回和接收轉換后的數據的正確方法是什么?

[英]What is the correct way to return and receive transformed data from an observable in an Angular service and component?

我有一個基本服務,它被配置為作為 Observable 工作。

我將服務注入到訂閱服務的以下方法的組件中,該方法會觸發對數據的 http 請求:

listApi(params:any) Observable<any[]> {
...
return this.http.get(params.url, ampOptions)
                    .map(data => this.listExtract(response, params))
                    .catch(this.handleError);
}

我需要循環並轉換響應,以確保在將響應返回到我的組件之前完成。

為了實現這一點,我嘗試使用帶有awaitPromise.allasync函數:

async listExtract(response:any, params:any) {
  let newArray:any = [];
  await Promise.all(response.map((item, index) => {
      if(item.id === params.id) {
       // make changes to specific item if it's id is a match
       item.label = 'selected';
      }
      newArray.push(item);
  });
  // I am assuming the above promise.all is guaranteed
  // to complete before returning the new array, correct?
  return newArray;
}

在我的組件中,我訂閱了服務中的listApi方法:

this.listService.listApi(params)
      .subscribe(
        response => this.listServiceResponse(response),
        error => this.serviceError = <any>error);

響應似乎正確通過,但是因為我使用了一個 promise 來轉換數據,所以它被包裝在一個名為ZoneAwarePromise的對象中:

listServiceResponse(response) {
   // because i used an async function in the service,
   // Angular returns the response wrapped in an
   // object titled ZoneAwarePromise
   console.log('response:',response);
}

如果我上面使用異步函數的方法對於首先轉換數據有效,我如何正確接收此響應? 或者我應該以完全不同的方式來解決這個問題?

我可以只從ZoneAwarePromise對象中提取響應,但這似乎並不可靠,僅作為示例,以下內容有效,但這也不可能是正確的方法:

listServiceResponse(response) {
       // attempt to use a .then to extract the data
       response.then((extractedArray) => {
         console.log('response:',extractedArray);
       }
}

是否有另一種方法可能使用更復雜的映射方法?

您應該能夠直接使用 observable。 在您的服務返回內容之前,不會觸發 subscribe 方法,因此您應該能夠在調用該方法之前完成所需的所有處理。 我認為您可以簡化您的listExtract以便它只處理將響應轉換為您的一系列內容的操作,而無需擔心任何異步業務。

listExtract(response:any, params:any): any[] {
  let results: any[] = response.results;
  return results.map(item => {
    if (item.id == params.id)
      item.label = 'selected';
    return item;
  });
}

然后您的listApi方法可以保持大致相同,但您實際上應該使用您擁有的data參數,這將是 http 響應。

listApi(params:any) Observable<any[]> {
  return this.http.get(params.url, ampOptions)
                    .map(data => this.listExtract(data, params))
                    .catch(this.handleError);
}

那么你在你的組件中使用這個 listApi 服務調用應該足夠簡單:

this.listService.listApi(params)
      .subscribe(array_of_things = this.workWithMyList(array_of_things));

這里的 observable 應該消除手動處理數據異步性質的任何需要。 當您的訂閱被觸發時,數據就已經存在了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM