What causes unexpected outcomes when using async / await with Array.map()?

Below is a functional version of my code that produces the expected output:

***.then(r => r.json()).then(async r => {

                    for (let i = 0; i < r.length; i++) {
                        let pipeline = r[i];
                        pipeline.collapsed = true;
                        pipeline.levels = await this.getPipelineLevels(pipeline.id);
                    }

                    this.project.pipelines.items = r;
                })

Here is the problematic version that is yielding unexpected results:

****.then(r => r.json()).then(r => {
                    let pipelines = r.map(async (value) => {
                        let levels = await this.getPipelineLevels(value.id);
                        return {...value, collapsed: true, levels: levels};
                    });

                    this.project.pipelines.levels = pipelines;

An odd result in the console when using

console.log(JSON.stringify(pipelines))
after *.map():

[{"_c":[],"_s":0,"_d":false,"_h":0,"_n":false},{"_c":[],"_s":0,"_d":false,"_h":0,"_n":false}]

Can you figure out what could be causing this issue?

Answer №1

Since Array.map does not await its passed callback, it disregards the fact that you labeled its callback as async.

Simply map your Promises using Array.map and then pass them to Promise.all, letting it handle the awaiting process in parallel for you.

const getPipelineLevels = id => new Promise(resolve => {
  setTimeout(() => resolve({ id: id, foo: 'bar' }), 500)
})

const idx = [1,2,3,4,5]

const tasks = idx.map(id => {
  return getPipelineLevels(id)
    .then(value => ({ ...value, bar: 'baz' }))
})

Promise.all(tasks)
  .then(results => {
    console.log(results)
  })

Answer №2

Consider implementing the following code snippet:

.then(async r => {
    let pipelines = await Promise.all(r.map(async value => {
        let levels = await this.getPipelineLevels(value.id);
        return {...value, collapsed: true, levels: levels};
    }));
    this.project.pipelines.levels = pipelines;
});

Array.map(async (value) => {...})
generates an array of Promises.

This approach would outperform the original intent, as it executes asynchronous tasks concurrently.

Furthermore, be mindful to avoid awaiting a .then(…) chain.

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

Apollo Client is not properly sending non-server-side rendered requests in conjunction with Next.js

I'm facing a challenge where only server-side requests are being transmitted by the Apollo Client. As far as I know, there should be a client created during initialization in the _app file for non-SSR requests, and another when an SSR request is requi ...

A guide on successfully implementing Nuxt-img on nuxt3 generate!

I've been experimenting with nuxt-image on NUXT3, but I've run into an issue when using the generate command. While images display correctly during development, they return a 404 error when using nuxt generate. In my nuxt config, I have: modules ...

The checkboxes do not appear to be updating visually when the "checked" property is toggled programmatically

Check out this example on JSFiddle for a demonstration. Clicking on a checkbox should cause all the neighboring checkboxes to toggle on or off. Even though the "checked" property is toggling, there doesn't seem to be any visual change. n.prop("chec ...

Is it possible to create a button function in HTML that can alter the CSS image tag?

Is there a way I could create a function that can retrieve a value, update an image source, and then incrementally select another value? It would be incredibly helpful if you could provide a reference where I could learn how to do this or explain it in det ...

Implementing custom logic in a Vuetify dialog box

Is it possible to trigger a dialog on a button click while executing some logic before and after the event? How can this be accomplished? Here is what I have attempted: template <v-dialog v-model="dialog" width="400"> <template v-slot:activat ...

Trouble with comparing two datetime values in JavaScript

I have a dilemma with two different appointments: appointment1 = "2013-07-08 12:30:00" appointment2 = "2013-07-08 13:30:00" My goal in JavaScript is to compare these two appointment dates. If they don't match, I want to remove the appointment; if t ...

What are the reasons animation fails to function properly in React?

Creating a chat feature using react/redux has been quite the journey. I fetch all the dialogs from the redux array and display an opening button for each one of them. Now, I want to add some animation when opening each dialog. To achieve this, I modify th ...

Utilize Angular to inject an input from a component directly into the header of my application

I am looking to customize my Pages by injecting various components from different Pages/Components into the header. Specifically, I want to inject an Input search field from my content-component into the header Component. I initially attempted to use ng-Co ...

Is there a way to trigger an ajax call specifically on the textarea that has been expanded through jQuery?

Whenever I expand a textarea from three textareas, all three trigger an ajax call. Is there a way to only call the ajax for the specific expanded textarea? I tried using $(this).closest('textarea').attr('id'), but it didn't work. A ...

Tips for submitting a form using javascript while preventing the default action

Looking for a way to submit a form in Javascript and prevent the default action? Let's explore how you can achieve this. Initially, my HTML form with the ID "contact_form" had an input element like so: <input id="contact_send_msg" type="submit" val ...

What is the best way to include a dialog div within a form tag?

I am facing an issue with a JQuery dialog on my webpage. The data entered into the dialog seems to get lost because the dialog is placed outside the form tag. Here is how it appears: https://i.stack.imgur.com/fnb07.png So far, I have attempted this soluti ...

JQuery-UI alert for Checkbox Selections

Clicking the link will trigger a dialog box to pop up. When the "Download Later" button is clicked, it will toggle the checked variable of the button and then close the dialog. I am just starting out with Javascript and JQuery, so I'm still trying to ...

Having trouble rendering JSON encoded data in a JqPlot Chart within a PHP script

I've spent the past few days scouring through Stack Overflow and various other websites, but I haven't been able to find a solution to my specific issue. Even the book 'Create Web Charts with JqPlot' by Fabio Nelli didn't provide t ...

Initiating Calls from JavaScript to JavaFX

I'm facing an issue while trying to execute a JavaScript function called testCheckMate from Java. The error message I receive is: Exception in thread "JavaFX Application Thread" netscape.javascript.JSException: SyntaxError: Unexpected EOF The WebVie ...

Exploring real-time data updates using React and the setInterval method

Every time my component loads, I am attempting to continuously poll the Spotify API using setInterval. However, during testing, an error message pops up: Invalid Hook Call..etc. I suspect that the issue stems from using useEffect within another useEffect w ...

Implementing Pagination for a JSON Object using Javascript and Jquery

I am looking for the most effective way to implement pagination in my current situation: I am using "$('body').append(htmlText);" to display the items from a JSON object. How can I set up pagination so that each page displays only one item based ...

Saving data from the Viewbag into a jQuery array or object on the client side

Imagine this scenario: I have a dynamic object called ViewBag, which is essentially a list filled with some results; Scenario 1: User 1 enters and populates the ViewBag.Products object with a list of 50 items; Scenario 2: User 2 enters and fills t ...

The test suite encountered an error while trying to run due to being unable to locate the module 'vue-template-compiler' when utilizing Jest in

I encountered an error in vue3 while trying to run tests with jest. Test suite failed to run Cannot find module 'vue-template-compiler This is the issue I faced when running the tests. I am aware that the package is related to vue2 and I have "vue/ ...

What is the best way to extract data from a jQuery JSON response that is wrapped in an object

Can someone help me with parsing a JSON answer that has the following structure? { "TariffItems": [ { "TariffId": "89", "TariffCode": "Y", "TariffRusName": "Эконом" }, { "Ta ...

Is there a way to inform the List component when the height of its row items has been altered in order to trigger a rerender

In my project, I am using a react-virtualized List where each item in the rows has an expand button. When this button is clicked, the row's height changes to reveal more information. The problem I am facing is that after clicking the button, the inne ...