在异步请求完成后返回数据的角度服务方法

时间:2019-06-27 08:11:08

标签: javascript angular

我有一个组件正在调用服务以获取数据; initAllData()

然后,此方法对某些json执行两次请求,并在返回数据后使用forkJoin处理数据。处理完所有数据后,我想在该方法中返回新数据(this.results),以便在组件中接收它。

这是我的方法:

initAllData() {

// Get player data
this.players = this.getPlayersData();

// Get results data
this.scores = this.getResultsData();

forkJoin([this.players, this.scores]).subscribe(data => {

  // data[0] is the players
  // data[1] is the scores
  let playersArray = data[0].Players;
  let scoresArray = data[1].Results;

  // Populate the results array by merging each player with their scores based on the PlayerId
  this.results = playersArray.map(player => {
      return Object.assign(
        {}, 
        player, 
        scoresArray.find(score => score.PlayerId === player.PlayerId),
        {"Position": null}
      );
  });

  // Sort the results array from highest TotalScore to lowest
  this.results.sort((a, b) => b.TotalScore - a.TotalScore);

  // Add a position value to the results
  this.results.forEach((item, index) => {
    item.Position = index + 1;
  });
  console.log(this.results)

}); 

return this.results // this is undefined until forkJoin completes :(

}

当前,它在forkJoin函数完成填充属性之前返回空值。

3 个答案:

答案 0 :(得分:3)

您需要返回一个可观察值。不要订阅initAllData,而是

return forkJoin([this.players, this.scores]).pipe(
    map(([players, scores]) => {

// Do the assignments here, and return results in the end:
        return this.results;
    }));
//...

现在,initAllData的消费者应该:

this.initAllData().subscribe(results => // now he has results

答案 1 :(得分:0)

返回fork从服务中加入Promise。 forkJoin Promise应返回所有数据的合并结果(此结果取决于您的情况)。

答案 2 :(得分:0)

使用承诺退货

initAllData() {
// Get player data
  this.players = this.getPlayersData();
  // Get results data
  this.scores = this.getResultsData();
  return new Promise((res,rej)=>
  {
    forkJoin([this.players, this.scores]).subscribe(data => {

      // data[0] is the players
      // data[1] is the scores
      let playersArray = data[0].Players;
      let scoresArray = data[1].Results;

      // Populate the results array by merging each player with their scores based on the PlayerId
      this.results = playersArray.map(player => {
          return Object.assign(
            {}, 
            player, 
            scoresArray.find(score => score.PlayerId === player.PlayerId),
            {"Position": null}
          );
      });

      // Sort the results array from highest TotalScore to lowest
      this.results.sort((a, b) => b.TotalScore - a.TotalScore);

      // Add a position value to the results
      this.results.forEach((item, index) => {
        item.Position = index + 1;
      });
      console.log(this.results)
      res(this.results)
    });
  });
}

呼叫方式:-

initAllData().then(data=>console.log(data));