How to fire multiple API calls asynchronously at the same time?

31,874

Solution 1

You could use Promise.all to wait for multiple requests in parallel:

async componentDidMount() {
  const [books, authors, shops] = await Promise.all([
    APIManager.fetchBooks(),
    APIManager.fetchAuthor(),
    APIManager.fetchShops(),
  ]);

  this.handleBooks(books);
  this.handleAuthors(authors);
  this.handleShops(shops);
}

This however waits for all 3 requests to be completed before calling handleBooks / handleAuthors / handleShops.

If you want them to call their handle method directly after they completed, you could use .then() on the individual fetch calls:

async componentDidMount() {
  await Promise.all([
    APIManager.fetchBooks().then(this.handleBooks),
    APIManager.fetchAuthor().then(this.handleAuthors),
    APIManager.fetchShops().then(this.handleShops),
  ]);
  // All fetch calls are done now
  console.log(this.state);
}

(this works because async functions always return a promise)

About your problem with the fetch calls, you might be affected by this react-native bug:
Multiple fetch request starts to not resolve or reject promise
According to the github issue page, it should be fixed in version 1.2.1 of react-native.

Solution 2

Hope so It will help you for multiple API calls simultaneously.

React.useEffect(()=>{
Promise.all([
    fetch('https://jsonplaceholder.typicode.com/posts'),
    fetch('https://jsonplaceholder.typicode.com/users')
]).then(function (responses) {
    // Get a JSON object from each of the responses
    return Promise.all(responses.map(function (response) {
        return response.json();
    }));
}).then(function (data) {
    // Log the data to the console
    // You would do something with both sets of data here
    console.log(data);
}).catch(function (error) {
    // if there's an error, log it
    console.log(error);
});
},[])
Share:
31,874
Isaac
Author by

Isaac

Jack of all trades, master of some

Updated on July 05, 2022

Comments

  • Isaac
    Isaac almost 2 years

    Basically I have a screen that calls multiple APIs at componentDidMount, and each and every API will fire a network request along with a callback, something as below

    componentDidMount() {
        new APIManager.fetchBooks(this.handleBooks);
        new APIManager.fetchAuthor(this.handleAuthor);
        new APIManager.fetchShops(this.handleShops);
    }
    
    ...
    
    handleBooks = (result) => {
      this.setState({ books: result });
    }
    ...
    

    And basically all the fetch methods works pretty similarly, it accepts a single parameter which is a callback from the component, pseudocode as below

    export async function fetchBooks(callback) {
      const result = await callNetworkAPI();
    
      callback(result);
    }
    

    This was working fine on both Android and iOS at react-native v0.53 but it's not working anymore at v0.59.10 on iOS.

    What's happening now is that, fetchBooks, fetchAuthor and fetchShops will all still be triggered but this.handleBooks, this.handleAuthor will no longer be triggered. It's like they lost their cursor.

    I've made it work such that all API calls has to be using await, something as below

    async componentDidMount() {
      const books = await APIManager.fetchBooks();
      const authors = await APIManager.fetchAuthor();
      const shops = await APIManager.fetchShops();
    
    
      this.handleBooks(books);
      this.handleAuthors(authors);
      this.handleShops(shops);
    }
    

    And of course updates to my APIManager as below:

    export async function fetchBooks() {
      const result = await callNetworkAPI();
    
      return result;
    }
    

    Its working fine, but all 3 API calls cannot be asynchronously anymore because I made it await for the previous API call before proceeding. I'm wondering if there's a better way to handle my problem? Or I'm totally on the right track?

  • cuongtd
    cuongtd almost 5 years
    can you explain why the callback way not working here?
  • Turtlefight
    Turtlefight almost 5 years
    @CuongTranDuc not really, for that we would need a bit more context what the actual error was you were getting and what callNetworkAPI() does to fetch the results. Your callback code looks ok, apart from the new before APIManager that shouldn't be necessary in your code example.
  • Isaac
    Isaac almost 5 years
    @Turtlefight: Truth is I'm not sure why it wasn't working with the callback way. As mentioned, it is working fine on Android but not working on iOS anymore
  • Turtlefight
    Turtlefight almost 5 years
    @Isaac you might be running into this issue: github.com/facebook/react-native/issues/21862 it seems to be a known bug in react-native
  • Isaac
    Isaac almost 5 years
    @Turtlefight: Gotta work on my Googling skills. Thanks for your elegant answer anyway!
  • Turtlefight
    Turtlefight almost 5 years
    @Isaac Glad i could help :) It should be fixed in version 1.2.1 of react-native, so updating it should hopefully fix the problem :)
  • Ernst Plesiutschnig
    Ernst Plesiutschnig over 3 years
    Multiple axios calls within one component did not work for me. Sometimes the request was mapping to the wrong props after receiving - inside mapStateToProps. Sometimes only one call etc. After separation of each axios call into a separate component and doing the imports, everything works fine. The solution, I would do is to either work on the api model and fetch the whole model-data within one call since they need to be related with pk and fk, or separate components for reliability and maintenance.