javascript - forEach 循环与异步代码?

标签 javascript reactjs foreach async-await frontend

我用不同的参数调用了 3 次函数:

this.getContributorProperties('followers_url', 'contributorFollowers');
this.getContributorProperties('gists_url', 'contributorGists');
this.getContributorProperties('repos_url', 'contributorRepositories');

这个函数看起来像这样:

async getContributorProperties(propertyUrl, propertyName) {
    const contributors = await this.addLinkToContributor();
    for (let i = 0; i < 10; i += 1) {
      axios.get(`${contributors[i][propertyUrl]}?per_page=100&${API_KEY}`).then((res) => {
        contributors[i][propertyName] = res.data.length;
      });
    }
    return contributors;
}

它循环遍历一组贡献者(对象类型)并为他们中的每一个进行 API 调用。我需要为它们中的每一个调用 3 个 API 调用,因此在开始时有三个调用。 为了干燥我的代码,我想像这样制作一个 forEach 循环:

[
      ['followers_url', 'contributorFollowers'],
      ['gists_url', 'contributorGists'],
      ['repos_url', 'contributorRepositories'],
    ].forEach(this.getContributorProperties);

forEach 循环在 componentDidMount() 当我调用 3 个电话时,它工作正常。但是当我做 forEach 时,我得到一个错误:

Uncaught (in promise) TypeError: Cannot read property 'addLinkToContributor' of undefined

如何让它发挥作用?

奖励:然后如何将这些键值对分配给每个对象?

最佳答案

参见 How to access the correct this inside a callback?和/或 How does the "this" keyword work?了解您收到特定错误消息的原因。

但从根本上说,您无论如何都不想将该函数传递给 forEach,因为 forEach 并未传递它想要的函数。

相反,只需使用箭头函数:

[
  ['followers_url', 'contributorFollowers'],
  ['gists_url', 'contributorGists'],
  ['repos_url', 'contributorRepositories'],
].forEach(pair => this.getContributorProperties(pair[0], pair[1]).catch(err => {/*...handle error...*/});

注意错误处理;我们不想要未处理的拒绝,并且 forEach 不会做任何事情将它们传播给调用者。


不过,不将返回值用于任何事情似乎很奇怪。也许 mapPromise.all:

const results = await Promise.all([
  ['followers_url', 'contributorFollowers'],
  ['gists_url', 'contributorGists'],
  ['repos_url', 'contributorRepositories'],
].map(pair => this.getContributorProperties(pair[0], pair[1])));

...确保在调用者不处理错误时处理错误。


请注意您的 getContributorProperties 函数中有两个错误:

  1. 返回前不等待 axios.get 完成(async 函数不自动await promise ,你必须明确)

  2. 它不处理拒绝 axios.get

    返回的 promise

我也很好奇重复调用 this.addLinkToContributor 三次是否正确,以及第二次两次是否会造成浪费。

在您提出的评论中:

Results are 3 arrays of the same objects (contributors) with just one property changed each. So one array has contributors with gists, another with followers, etc. Do I now somehow concatenate them or is it better to do that in getContributorProperties function?

那是我的直觉。像这样的东西:

async getContributorProperties(properties) {
    const contributors = await this.addLinkToContributor();
    return Promise.all(contributors.map(contributor =>
      Promise.all(properties.map(property =>
        axios.get(`${contributor[property.url]}?per_page=100&${API_KEY}`).then(res => {
          contributor[property.name] = res.data.length;
        })
      ));
    ));
}

这样调用:

const results = await this.getContributorProperties([
  {url: 'followers_url', name: 'contributorFollowers'},
  {url: 'gists_url',     name: 'contributorGists'},
  {url: 'repos_url',     name: 'contributorRepositories'}
]);

(我们真的需要 await.all concept,这样上面的内容就不会混淆其隐喻...)

关于javascript - forEach 循环与异步代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46402686/

相关文章:

javascript - 尝试在node.js上模拟function.bind()

javascript - 如何创建自定义 polymer 元素的方法并在主应用程序中调用它?

java 8 : Change value inside stream

java - 使用 stream.foreach() 打印元素不起作用

php - 存储多维数组中的特定值

javascript - 用JQuery在div中插入html删除Anchor标签

javascript - Sails.js 将 key 和数据流式传输到 Angular

reactjs - 使用 firebase-functions 部署基于 React 的 SSR 应用程序时出错

javascript - 在不触发重新渲染的情况下调用 setState

reactjs - 通过 Azure Function 和 auth0 进行存储帐户应用程序身份验证