para cada bucle con código asíncrono?

Estoy haciendo una llamada de function 3 veces con diferentes arguments:

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

Esta function se ve así:

 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; } 

Pasa por una matriz de contribuyentes (tipo de object) y realiza una llamada API para cada uno de ellos. Necesito hacer 3 llamadas API para cada una de ellas, por lo tanto, las tres llamadas al principio. Para SECAR mi código, quería hacer un bucle forEach así:

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

forEach loop está en componentDidMount() Cuando hago 3 llamadas, funciona bien. Pero cuando lo hago por cada vez que recibo un error:

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

¿Cómo hago que funcione?

BONIFICACIÓN: ¿Cómo puedo asignar esos pares key-valor a cada object?

Consulte ¿Cómo acceder a this correcto dentro de una callback? y / o ¿cómo funciona la palabra key "this"? por qué tenías ese post de error específico.

Pero, fundamentalmente, no querrás pasar esa function a forEach todos modos, ya que forEach no pasa esa function lo que quiere.

En cambio, solo usa una function de flecha:

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

Tenga en count el event handling errores; no queremos rechazos no controlados, y para cada forEach no hace nada para propagarlos a la persona que llama.


Sin embargo, parece extraño no utilizar el valor de retorno para nada. Quizás map y Promise.all :

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

… asegurándose de manejar los errores si la persona que llama no lo hace.


Tenga en count que hay dos errores en su function getContributorProperties :

  1. No espera a que los axios.get completen antes de regresar (las funciones async no await promises de manera automática, debe ser explícito)

  2. No maneja los rechazos de la promise devuelta por axios.get

También tengo curiosidad si repetir la llamada a this.addLinkToContributor tres veces es correcto, y si puede ser un desperdicio las segundas dos veces.

En un comentario que has preguntado:

Results son 3 matrices de los mismos objects (queueboradores) con una sola propiedad cambiada cada uno. Entonces, una matriz tiene queueboradores con ideas, otra con seguidores, etc. ¿Los concateno de alguna manera o es mejor hacerlo en la function getContributorProperties ?

Ese sería mi instinto. Algo como:

 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; }) )); )); } 

llamado así:

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

(Realmente necesitamos ese concepto await.all para que lo anterior no mezcle sus metáforas …)