简体   繁体   中英

How to wait for .map() to finish executing before continuing on to next lines of code

How do I go about waiting for all the posts to be pushed to the posts array before updating the state?

I had to iterate over an array of post ID's to get the top posts on HackerNews and then turned all those ID's into singular post links and want to store the data from the single post links in an array so I can iterate over that array to render it in the DOM.

 import React, {Component} from 'react'; import axios from 'axios'; import Post from './Post'; class ContentWrapper extends Component { constructor(props){ super(props); this.state = { posts: [] } } componentDidMount(){ const topStories = 'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty'; // `https://hacker-news.firebaseio.com/v0/item/.json?print=pretty` axios(topStories).then(res => { const posts = []; res.data.map(val => { const url = `https://hacker-news.firebaseio.com/v0/item/${val}.json?print=pretty`; return axios.get(url).then(res => { posts.push(res.data); }).then(res => this.setState({posts: res})); }); }); } render() { const posts = this.state.posts.map((val, i) => { return <Post key={i} title={val.title} author={val.by} /> }); return ( <div className="content-wrapper"> <h2>{this.props.currentSource}</h2> {posts} </div> ) } } export default ContentWrapper;

You will have to use Promise.all - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

const topStories =
  "https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty";

axios(topStories).then(res => {
  const posts = [];

  const requests = res.data.map(val => {
    const url = `https://hacker-news.firebaseio.com/v0/item/${val}.json?print=pretty`;
    return axios.get(url).then(res => {
      posts.push(res.data);
    });
  });

  // Wait for all requests, and then setState
  return Promise.all(requests).then(() => {
    this.setState({
      posts
    });
  });
});

Test it here: https://runkit.com/embed/8pac53dhmy2y


Update There is also Promise.allSettled which might be better in some cases if there are any errors in the promise array; https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM