【问题标题】:Pushing elements into the array works only inside the loop将元素推入数组仅在循环内有效
【发布时间】:2019-12-06 00:27:29
【问题描述】:

我得到了一些从 API 调用的数据,为此我使用 axios。当检索到数据时,我将其转储到一个名为“RefractorData()”的函数中,只是为了对其进行一点组织,然后将其推送到现有数组中。问题是,我的数组被填充到 forEach 中,我可以在那里 console.log 我的数据,但是一旦我退出循环,我的数组就是空的。

let matches: any = new Array();
const player = new Player();

    data.forEach(
          async (match: any) => {
            try {
              const result = await API.httpRequest(
                `https://APILink.com/matches/${match.id}`,
                false
              );
              if (!result) console.log("No match info");
              const refractored = player.RefractorMatch(result.data);
              matches.push({ match: refractored });
              console.log(matches);
            } catch (err) {
              throw err;
            }
          }
        );
        console.log(matches);

现在 forEach 中的第一个 console.log 可以正常显示数据,forEach 之后的第二个显示空数组。

【问题讨论】:

    标签: javascript arrays node.js typescript


    【解决方案1】:

    通过Promise.all()Array.prototype.map() 设法做到这一点。

    const player = new Player();
    const matches = result.data;
    
    const promises = matches.map(async (match: any) => {
      const response: any = await API.httpRequest(
        `https://API/matches/${match.id}`,
        false
      );
    
      let data = response.data;
      return {
        data: player.RefractorMatch(data)
      };
    });
    const response: any = await Promise.all(promises);
    

    【讨论】:

      【解决方案2】:

      您必须了解async 函数几乎总是在稍后运行,因为它们依赖于一些外部输入,例如 http 响应,因此,第二个 console.log 在第一个之前运行。

      有几种方法可以解决这个问题。最丑陋但最容易弄清楚的是创建一个外部承诺,一旦所有 http 请求完成,您将解决该承诺。

      let matches = [];
      let promise = new Promise((resolve) => {
          let complete = 0;
          data.forEach((match: any) => {
              API.httpRequest(...).then((result) => {
                  // Your logic here
                  matches.push(yourLogicResult);
                  complete++;
                  if (complete === data.length) {
                      resolve();
                  }
              }
          }
      };
      
      console.log(matches); // still logs empty array
      
      promise.then(() => console.log(matches)); // now logs the right array
      

      您可以使用其他方法解决此问题,例如Promise.all()

      一个非常有用的解决方法是使用 RxJs Observables。见https://www.learnrxjs.io/

      希望能帮到你!

      【讨论】:

      • 感谢您的回答,您帮了我很大的忙!在Promise.all() 的帮助下,我以类似的方式做到了这一点。我会发布我的答案,以便其他人可以查看。
      • 很高兴我帮助您找到了自己的出路!
      猜你喜欢
      • 2015-07-10
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多