如何解决.subscribe的异步执行并将数据绑定在一起?

时间:2019-02-07 12:23:35

标签: angular typescript

我需要调用一个给我2个值的API:一个链接和一个ID。 看起来像这个例子:

{'link' : ['link1','link2'], 'id' : ['id1','id2']}

每个链接都是一个API,所以我在for循环中再次调用它们,然后,我检索了Movie类型的数据,将其添加到movie中并使用回调发送。

问题是id不能正确绑定到链接,因为我使用.subscribe,有时我最终将id1分配给link2。

这是代码:

onSubmit() {
    this.submitted = true;

    if (this.searchForm.invalid) {
        return;
    }
    //call first API
    this.movieService.getMovieLink(this.f.search.value) 
        .subscribe(response => {
          this.idStr = response['link']  // string of links
          this.myIdS = response['id']   // string of id's

          for (let index in this.idStr) {
            this.myId = this.myIdS[index] 
            this.movieService.id = this.idStr[index]; 
            //call API I got from links
            this.movieService.getMovie2()  
                  .subscribe( response => {

                        this.movies.push({
                        // this does not correspond to the actual id
                        id : this.myId,  
                        name : response['Title'],
                        releaseDate : response['Released'],
                        genres : response['Genre'],
                        description : response['Plot'],
                        starRating : response['imdbRating'],
                        imageUrl : response['Poster']
                      })  
                      //send data from .subscribe with a function
                      if (Number(index) == this.idStr.length - 1) {
                             this.mycallback(this.movies)
                      }

                    },
                    err => {console.error(err)
                 })  
          }    
          this.movies = [];
})
}

我的问题是如何将链接与ID绑定在一起,以便电影中的值相对应?

2 个答案:

答案 0 :(得分:0)

使用mergeMap / flatMap而不是多个订阅。

this.movieService.getMovieLink(this.f.search.value) 
        .mergeMap(response => {
          let links = response['link']  // array of links
          let ids = response['id']   // array of ids

          return ids.map( (myId,index) => {
            let link = links[index];  // <-- where is this used ?
            return this.movieService.getMovie2() // <-- probably pass link here instead of depending on side-effect by setting movieService.id 
                  .map( res =>   
                        ({
                        id : myId,  
                        name : response['Title'],
                        releaseDate : response['Released'],
                        genres : response['Genre'],
                        description : response['Plot'],
                        starRating : response['imdbRating'],
                        imageUrl : response['Poster']
                        })
                     )
                 })  
          })
}).subscribe(val => //should give you the array you are expecting...

答案 1 :(得分:0)

this.myId = this.myIdS[index]每次在API响应时都重新分配该类的myId属性,因此this.myId的值不可靠。例如,先创建一个请求A,然后创建请求B,但请求B在请求A之前完成,然后按错误的顺序更改值。

所以不要使用

this.movies.push(...)

id: this.myId

,请使用

this.movies[index] = ...

id: this.idStr[index]

希望获得帮助