javascriptnode.jsaxiosinquirerjs

Running several Axios requests in parallel to validate data


I'm using Inquirer.js to interact with a user. In one of the dialogs, the user can specify a comma-separated list of "items". The following validation function checks against an API, whether the "item" is available. If not, the user is prompted to make corrections to his previous selection.

Current code:

validate: async str => {    
  const items = str.split(',');    

  for(let item of items) {
    try {
      await axios.get(`https://api.example.com/items/${item}`);
    } catch(e) {
      return `The item '${item}' could not be found`;
    }
  }   

  // data exists, but is irrelevant
  return true;
}

While this all works as it should, iterating over an array of packages and calling axios.get() on each item seems terribly inefficient. Is there a way to run these in parallel and break once one of the requests failed?

Again, I'm not interested in the actual data of an item, but just whether it exists (equals true) or not (returns an error message).


Solution

  • The first thing to look at is that JavaScript can't really run things in "parallel" in a traditional sense because it is not a multi-threaded environment.

    You can however, send all the API calls in one block and then await the responses together instead of awaiting each one before sending the next. This can be accomplished using the Promise API's Promise.all See below:

    var promises = [];
    for(let item of items) {
        promises.push(axios.get(`https://api.example.com/items/${item}`));
    }
    try {
        var responses = await Promise.all(promises); // responses will be an array
    } catch (err) {
        // do something with error
    }
    

    And here the Promise.all docs

    edit: I added a try/catch block to match the OP.