簡體   English   中英

Angular2-多個相關的順序http api調用

[英]Angular2 - Multiple dependent sequential http api calls

我正在構建Angular2應用程序,並且其中一個組件需要進行多個API調用,而這些調用取決於先前的調用。

我目前有一項服務,可以通過API調用來獲取電視節目列表。 對於每個節目,然后我需要多次調用不同的API來逐步遍歷結構,以確定該節目是否存在於Plex服務器上。

API文檔在這里

對於每個節目,我需要進行以下調用並獲取正確的數據以確定它是否存在:(假設我們有變量<TVShow>, <Season>, <Episode>

http://baseURL/library/sections/?X-Plex-Token=xyz會告訴我: title="TV Shows" key="2"

http://baseURL/library/sections/2/all?X-Plex-Token=xyz&title=<TVShow>會告訴我: key="/library/metadata/2622/children"

http://baseURL/library/metadata/2622/children?X-Plex-Token=xyz會告訴我: index="<Season>" key="/library/metadata/14365/children"

http://baseURL/library/metadata/14365/children?X-Plex-Token=xyz會告訴我: index="<Episode>"暗示我已經存在。

響應位於json中,我刪除了很多多余的文本。 在每個階段,我需要檢查是否存在正確的字段( <TVShow>, <Season>, <Episode> ),以便將它們用於下一個呼叫。 如果沒有,我需要返回該節目不存在。 如果是這樣,我可能想返回該節目的ID。


我查看了很多示例,包括Promise,Async和Flatmap,但不確定如何根據我所看到的其他示例來解決此問題。


這是我獲得演出清單的條件。 (shows.service.ts)

export class ShowsHttpService {
    getShows(): Observable<Show[]> {
        let shows$ = this._http
            .get(this._showHistoryUrl)
            .map(mapShows)
            .catch(this.handleError);
        return shows$;
    }
}

function mapShows(response:Response): Show[] {
    return response.json().data.map(toShow);
}

function toShow(r:any): Show {
    let show = <Show>({
        episode: r.episode,
        show_name: r.show_name,
        season: r.season,
        available : false,    // I need to fill in this variable if the show is available when querying the Plex API mentioned above.
    });
    // My best guess is here would be the right spot to call the Plex API as we are dealing with a single show at a time at this point, but I cannot see how.
    return show;
}

這是組件中的相關代碼(shows.component.ts)

public getShows():any {
    this._ShowsHttpService
        .getShows()
        .subscribe(w => this.shows = w);
    console.log(this.shows);
}

獎勵積分

以下是一些有趣但又不必要的顯而易見的下一個問題:

  1. 第一個API查詢比等待所有其他查詢發生要快得多(4個查詢*約10個顯示)。 准備好時,可以返回初始列表,然后以available狀態更新初始列表。
  2. 第一次Plex調用獲取key="2"只需要執行一次。 它可能是硬編碼的,但是可以執行一次並記住嗎?
  3. 有沒有辦法減少API調用次數? 我可以看到可以刪除顯示過濾器,並在客戶端上搜索結果,但這也不理想。
  4. 每個節目的4個呼叫必須按順序進行,但是可以並行查詢每個節目的速度。 這可以實現嗎?

任何想法將不勝感激!

不知道我是否完全理解您的問題,但這是我的工作:

我進行第一個http調用,然后在訂閱激發時,它調用completeLogin。 然后,我可以使用自己的完整功能觸發另一個http調用,並重復該鏈。

這是組件代碼。 用戶已填寫登錄信息並按登錄鍵:

onSubmit() {
   console.log(' in on submit');
   this.localUser.email = this.loginForm.controls["email"].value;
   this.localUser.password = this.loginForm.controls["password"].value;
   this.loginMessage = "";
   this.checkUserValidation();
}

checkUserValidation() { 
   this.loginService.getLoggedIn()
      .subscribe(loggedIn => {
         console.log("in logged in user validation")
         if(loggedIn.error != null || loggedIn.error != undefined || loggedIn.error != "") {
            this.loginMessage = loggedIn.error;
         }
      });

      this.loginService.validateUser(this.localUser);
}

這將調用loginservice ValidateUser方法

validateUser(localUser: LocalUser) {
   this.errorMessage = "";
   this.email.email = localUser.email;
   var parm = "validate~~~" + localUser.email + "/"
   var creds = JSON.stringify(this.email);
   var headers = new Headers();
   headers.append("content-type", this.constants.jsonContentType);

   console.log("making call to validate");
   this.http.post(this.constants.taskLocalUrl + parm, { headers: headers })
      .map((response: Response) => {
         console.log("json = " + response.json());
         var res = response.json();
         var result = <AdminResponseObject>response.json();
         console.log(" result: " + result);
         return result;
      })
      .subscribe(
         aro => {
            this.aro = aro
         },
         error => {
            console.log("in error");
            var errorObject = JSON.parse(error._body);
            this.errorMessage = errorObject.error_description;
            console.log(this.errorMessage);
         },
         () => this.completeValidateUser(localUser));
            console.log("done with post");
     }

completeValidateUser(localUser: LocalUser) {
   if (this.aro != undefined) {
      if (this.aro.errorMessage != null && this.aro.errorMessage != "") {
         console.log("aro err " + this.aro.errorMessage);
         this.setLoggedIn({ email: localUser.email, password: localUser.password, error: this.aro.errorMessage });
      } else {
         console.log("log in user");
         this.loginUser(localUser);
      }
   } else {
      this.router.navigate(['/verify']);
   }

}

在我的登錄服務中,我調用了授權服務,該服務返回了可觀察的令牌。

loginUser(localUser: LocalUser) {
   this.auth.loginUser(localUser)
   .subscribe(
      token => {
         console.log('token = ' + token)
         this.token = token
      },
      error => {
         var errorObject = JSON.parse(error._body);
         this.errorMessage = errorObject.error_description;
         console.log(this.errorMessage);
         this.setLoggedIn({ email: "", password: "", error: this.errorMessage });
      },
      () => this.completeLogin(localUser));
}

在授權服務中:

loginUser(localUser: LocalUser): Observable<Token> {
   var email = localUser.email;
   var password = localUser.password;

    var headers = new Headers();
    headers.append("content-type", this.constants.formEncodedContentType);

    var creds:string = this.constants.grantString + email + this.constants.passwordString + password;
    return this.http.post(this.constants.tokenLocalUrl, creds, { headers: headers })
         .map(res => res.json())
}

此代碼中的要點是,首先根據返回信息響應返回信息(如果有效),首先調用登錄服務的validateUser方法,然后在登錄服務上調用loginUser方法。 只要您需要,此鏈可以繼續。 您可以設置類級別的變量來保存在鏈的每個方法中所需的信息,以決定下一步該做什么。

還要注意,您可以訂閱服務中的返回並在那里進行處理,而不必返回組件。

好的,這里是:

public getShows():any {
   this._ShowsHttpService
      .getShows()
      .subscribe(
         w => this.shows = w,
         error => this.errorMessage = error,
         () => this.completeGetShows());
}

completeGetShow() {

   //any logic here to deal with previous get;

   this.http.get#2()
      .subscribe(
         w => this.??? = w),
         error => this.error = error,
         () => this.completeGet#2);
}

completeGet#2() {

   //any logic here to deal with previous get;

   this.http.get#3()
      .subscribe(
         w => this.??? = w),
         error => this.error = error,
         () => this.completeGet#3);
}

completeGet#3() {

   //any logic here to deal with previous get;

   //another http: call like above to infinity....
}

暫無
暫無

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

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