Issue with using async await in map function: async function may not complete before moving on to the next item in the

Currently, I have an array that needs to be mapped. Inside the mapping function, there is an asynchronous function being called, which conducts an asynchronous request and returns a promise using request-promise.

My intention was for the first item in the array to be mapped, then perform the request, followed by the second item repeating the same process. However, this sequence is not occurring as expected in my current scenario.

Here is the function in question:

const fn = async() => {
  const array = [0, 1, 2];
  console.log('begin');
  await Promise.all(array.map(item => anAsyncFunction(item)));
  console.log('finished');
  return;
}

The anAsyncFunction looks like this:

const anAsyncFunction = async item => {
  console.log(`looping ${item}`);
  const awaitingRequest = await functionWithPromise(item);
  console.log(`finished looping ${item}`);
  return awaitingRequest;
}

And here's where the request is being made in functionWithPromise:

const functionWithPromise = async (item) => {
  console.log(`performing request for ${item}`);
  return Promise.resolve(await request(`https://www.google.com/`).then(() => {
    console.log(`finished performing request for ${item}`);
    return item;
  }));
}

Looking at the console logs I currently have:

begin
looping 0
performing request for 0
looping 1
performing request for 1
looping 2
performing request for 2
finished performing request for 0
finished looping 0
finished performing request for 1
finished looping 1
finished performing request for 2
finished looping 2
finished

However, what I was aiming for is:

begin
looping 0
performing request for 0
finished performing request for 0
finished looping 0
looping 1
performing request for 1
finished performing request for 1
finished looping 1
looping 2
performing request for 2
finished performing request for 2
finished looping 2
finished

Although this workflow pattern usually suffices, it appears that I might be receiving some invalid results from the request call due to possibly making too many requests simultaneously.

If anyone has suggestions on more effective methods to achieve my desired outcome, please do share.

Answer №1

.map() is not designed to handle asynchronous tasks or promises. It simply takes the value returned from its callback function and adds it to the result array without waiting for any promise to resolve. This behavior cannot be changed as that's how .map() works.

Instead of using .map(), you can utilize a for loop and utilize the await keyword inside the loop to properly handle async functions, causing them to pause until resolved.


Your current code:

await Promise.all(array.map(item => anAsyncFunction(item)));

runs all anAsyncFunction() calls in parallel and waits for all of them to finish simultaneously.


To run these functions sequentially, utilize a for loop and await each individual function call like this:

const fn = async() => {
  const array = [0, 1, 2];
  console.log('begin');
  for (let item of array) {
      await anAsyncFunction(item);
  }
  console.log('finished');
  return;
}

It's important to note that array iteration methods such as .map(), .filter(), and .forEach() are not built to handle asynchronous operations. If you need to sequence your async functions, opt for a regular for loop which can properly pause execution when utilizing async functions within it.

Answer №2

If you're looking to optimize your code, consider swapping out this snippet:

await Promise.all(array.map(item => anAsyncFunction(item)));

Try integrating this instead:

await Promise.all(array.map(async (item) => await anAsyncFunction(item)));

This method aligns more closely with the principles of node.js programming rather than using a traditional for loop. It's best to steer clear from using forEach in this scenario.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to retrieve a value from a JSON object using AngularJS?

Using nodeJS, the server sends a JSON object to the controller: data = { "question": "theQuestion", "answer": "theAnswer" }; res.json(data); In the controller, I attempt to manipulate the variable as follows: data = QA.get(); $scope.q = data[que ...

What is the best way to define a custom route in react-router-dom?

My goal is to have the URL display "/login" in the address bar when I am on the login page. // App.js <Routes> {isLoggedIn ? ( <Route path="/" element={<Root onLogout={handleLogout} />}> <Route index e ...

Looking to confirm the accuracy of file inputs on Node.js

I am currently developing my application using the Node + Express + MongoDB stack. Within my application, there are several forms for uploading files. While the uploading process works smoothly, I am facing an issue with the lack of validation for these fi ...

Sending target information as a property argument

I have encountered an issue with my app's two Bootstrap modals. It seems that many people are facing problems with opening the second modal. Is it possible to pass data-target and modal id properties as props in this manner: data-target={props.da ...

How can I add rows to the tbody of a table that is already inside a div container?

I have an existing table and I want to append a tbody element to it. Below is an example of the HTML table: <div id="myDiv"> <table class="myTable"> <thead> <tr> <th>ID</th> ...

Attempting to transfer user information to MongoDB using AngularJS and Node.js

Greetings everyone! I am currently working on a template and trying to develop a backend for it, starting with the registration form. Despite having some kind of connection between my mongodb and my app, data is not being sent to the database. Here is the ...

Massive HTML Table Containing Rows upon Rows

Currently, I have a server that can provide me with a list of objects in json format, and my goal is to showcase them in a table on the client side. Initially, I thought about dynamically modifying the DOM after receiving data from the server. Building th ...

Attempting to alter the background image through the action of clicking on an image using jQuery, HTML, and CSS

I have created custom weather icons like a sun, cloud, and rainy cloud using Photoshop. My goal is to allow users to click on these icons and change the background image of the website's body. However, despite my efforts, clicking on the images does n ...

Issues arise when utilizing external scripts alongside <Link> components in ReactJS, resulting in them becoming unresponsive

I'm experiencing some difficulties with an external script when using <Link to="/">. The script is included in the main layout file index.js as componentDidMount () { const tripadvisorLeft = document.createElement("script"); tripadvisorLef ...

Show brief tags all on one line

This image showcases the functionality of the site, specifically in the "Enter a code" column where users can input data using TagsInput. I am seeking to enhance this feature by ensuring that shorter tags are displayed on a single line. While I am aware th ...

The search bar is visible on desktop screens and can be expanded on mobile devices

Check out my code snippet below. <style> #searchformfix { width: 50%; border-right: 1px solid #E5E5E5; border-left: 1px solid #E5E5E5; position: relative; background: #fff; height: 40px; display: inline-block; border: ...

JavaScript - Two tables shown in parallel

Beginner coder seeking assistance! I am currently working on an application with two user input fields placed adjacent to each other. Clicking parse buttons next to these fields generates two separate tables. However, I need these tables to be displayed si ...

Troubleshooting auth error with Android and nativescript-plugin-firebase

I am currently utilizing this plugin in my application: https://github.com/EddyVerbruggen/nativescript-plugin-firebase Unfortunately, when using my real device on a 3G network, I encounter the following error: auth/network-request-failed Thrown if a netw ...

Unable to incorporate an external JavaScript file via a static URL

I'm attempting to link an external javascript file using a static URL, like this: <script type="text/javascript" src="{{ url_for('static/js', filename='test.js') }}"></script> However, I am encountering the following ...

I'm trying to determine which jQuery event would be more beneficial for my needs - should I go with

I'm facing a dilemma On my website, I need to capture the value of a span within a modal. The value changes when the modal is opened and reverts to the old value when closed. This particular value represents the cart total in my online store. Wheneve ...

Express generator causing routing issues

I decided to use the express generator and ran the command express --ejs. Everything seemed fine as I entered npm start in the terminal and visited http://localhost:3000/. Next, I attempted to create a new route '/shop' by adding the following c ...

Having trouble extracting the date modified from a JSON file

I am able to retrieve section name, URL, web title, and headline from parsing JSON data with this code snippet. However, I seem to be encountering an issue where I cannot extract the last modified date. Here is the JSON structure: { "response":{ ...

`Enhance Image with a Fresh Hue`

Let me explain my dilemma: I'm dealing with a two-tone png image - one tone is black and the other is transparent. Right now, I'm relying on the background color attribute to dynamically change the color of the transparent section. However, I ...

Remove hidden data upon moving cursor over table rows after a delay

Hey there! I'm in need of a little assistance, so I hope you can lend me a hand. Here's the scenario: Within my category table, there are numerous rows, each containing a hidden textbox with an empty value and a unique ID. As users navigate t ...

Javascript - Error encountered when utilizing a for loop to insert a new column into an array

I have been utilizing an API to fetch data on various stocks, and I am attempting to include a column named "symbol" with the query values using the function insertColumn. However, I am encountering an error message that says (node:15732) UnhandledPromiseR ...