Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 878
Isaac Avatar asked Jul 25 '19 14:07

Isaac


People also ask

What is the best way to trigger multiple API calls asynchronously?

If you want to call multiple API calls simultaneously, there's a better approach using Promise. all() . But if one API calls requires data from another, returning the fetch() method like this provides a simple, readable, flat structure and let's you use a single catch() for all of your API calls.

Can you make multiple API calls at once?

If you need to make multiple API requests, you can send these API requests concurrently instead of sending them one by one. Sometimes, we need to make multiple API calls at once. For example, let's say we have an array, and we want to make an API request for each element of that array.


2 Answers

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);
});
},[])
like image 81
Mirza Hayat Avatar answered Sep 16 '22 23:09

Mirza Hayat


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.

like image 45
Turtlefight Avatar answered Sep 19 '22 23:09

Turtlefight