如何使用for循环构建承诺响应的数组?

时间:2019-06-17 14:46:28

标签: javascript angular typescript ionic-framework

我正在构建一个Angular应用程序,以显示我网站的文章和投票,并且我想根据他们的投票对它们进行排序。我可以检索进行http调用的选票,尤其是:

  1. 我必须拨打http来检索类别列表及其ID列表(我经常在网站中添加类别,因此我需要更新我的应用)
  2. 我必须使用这些ID对每个ID进行一次http调用,以获取该特定类别的文章列表。
  3. 每篇文章都有一个ID,我必须存储每个ID才能对每个文章ID进行另一个http调用。
  4. 最后,每个n.3)响应对象都具有'users_vote'属性。然后,我需要构建一个数组以合并所有投票,然后对该数组进行排序。 然后,我将在HTML代码上显示该数组。

我不知道如何链接诺言,因此代码只是为了阐明我的意思。我也知道这确实很“棘手”,但目前我无法更改服务器端的任何内容,因此必须处理。

 ngOnInit() {
    this.getCategories()
    .then((res) => {
      this.getIds(res)
      .then((res) => {
        this.getArticlesList(res)
        .then((res) => {
          this.mergeArticlesList(res)
        })
      })
    })
  }


// 1) getCategories() to get the list 

  getCategories() {
      var promise = new Promise((resolve) => {
        this.myService.getCategoriesList()
        .subscribe((res) => {
          this.categories = res;
          resolve(this.categories);
        })
      })
      return promise;
    }

// 2) getCategoriesIDs(res) to get their IDs and store them in this.ids

  getCategoryIDs(res) {
    var promise = new Promise((resolve) => {
      for (let i=0; i < Object.keys(res).length; i++) {
        this.ids[i] = res[i+1]['id']
      }
      resolve(this.ids)
    })
    return promise;
  }

// 3) getArticlesList(res) to get the list of articles of each category

  getArticlesList(res) {
    var promise = new Promise((resolve) => {
      for (let i=0; i < Object.keys(res).length; i++) {
        this.myService.getArticlesOfCategory(res[i])
        .subscribe((res) => {
          this.allarticleslist[i] = res;
        })
      }
      resolve(this.allarticleslist)
    })
    return promise;
  }

// 4) mergeArticleIds(res) to create another array of ids (this time is // the list of articles' IDs

  mergeArticleIds(res) {
    console.log("Start merging with:")
    console.log(res)
    console.log(res.length)
    console.log(Object.keys(res).length)
    for (let i=1; i < Object.keys(res).length -1; i++) {
      for (let _i=0; _i < res[i]['reviews'].length; _i++) {
        this.mergedArticles = res[i]['reviews'][_i]['id']      }
    }
    return this.mergedArticles
  }

// 5) getArticle(res) to get the article with that particular ID
// With this http call I finally can get 'article_vote' and I have to 
// save this value in order to sort the array. 
// It has to return the array sorted

  getArticle(res) {
    // ??
 }

}

consolelog

它不起作用,因为console.log(res.length)返回0,所以for循环甚至没有开始。我知道我也必须处理异步操作计时,但是我不知道该怎么做。

编辑: 从myService添加getCategoriesList():

getCategoriesList(): Observable<any[]> {
    let url = 'myurl';
    return this.httpClient.get(url)
}

EDIT2: 添加getCategoriesList()的http.get响应:

{"5":{"description":"","title":"SOCCER""term_id":280,"room_name":"SOCCER"},
"4":{"description":"","title":"NFL","term_id":281,"room_name":"NFL"},
"3":{"description":"","title":"MLB","term_id":282,"room_name":"MLB"},
"2":{"description":"","title":"NHL","term_id":283,"room_name":"NHL"},
"6":{"description":"","title":"TENNIS","term_id":284,"room_name":"TENNIS"},
"1":{"description":"","title":"F1","term_id":285,"room_name":"F1"}}

2 个答案:

答案 0 :(得分:2)

您可以通过创建类似这样的承诺数组来轻松地链接承诺

let promiseArray: Promise<any>[] = [];

然后您可以通过使用push

添加Promise功能
var promise = new Promise();
promiseArray.push(promise);

您可以使用Promise.all(promiseArray).then((responses) => { ... })来解决阵列中的所有诺言

我希望它能对您有所帮助!

答案 1 :(得分:2)

请尝试以下代码-

// assuming that this.myService.getCategoriesList() returns an observable which has all categories
    this.myService.getCategoriesList()
        .pipe(
          switchMap(categories => {
            // NOTE - You should use category Id; I dont know the property which represents categoryId;
            // Replace cat.categoryId with your ID of a category
            const observables = categories.map(cat => this.myService.getArticlesOfCategory(cat.categoryId));
            return forkJoin(observables);
          }),
          switchMap(arrayOfArticlesByCategoryId => {
            // NOTE - You should use article Id; I dont know the property which represents articleId;
            // Replace article.articleId with your ID of an article
            const observables = arrayOfArticlesByCategoryId.map(article => this.myService.getArticle(article.articleId));
            return forkJoin(observables);
          }),
          map(arrayOfallArticles => {
            //You can also use 'pluck' operator - https://www.learnrxjs.io/operators/transformation/pluck.html
            return arrayOfallArticles.map(article => article.users_vote);
          }),
          map(arrayOfUsersVote => {
            console.log(arrayOfUsersVote);
            // Do whatever you want to do with arrayOfUsersVote i.e. sort them
          })
        ).subscribe();