Tips for patiently anticipating the outcome of asynchronous procedures?

I have the given code snippet:

async function seedDb() {
  let users: Array<Users> = [ ... ];
  applications.map(async (user) => await prisma.user.upsert(
    { create: user, update: {}, where: { id: user.id } }));
}

async function main() { 
  await seedDb(); 
  await seedDb2();  // This requires the update in seedDb() to have completed
}

The problem here is that other functions like seedDb2 rely on the presence of users in the database before running. While all updates start in seedDb, there is no actual waiting (blocking) until those functions finish.

What I want is to wait until all the async functions spawned by the map method return. How can this be achieved?


I am unsure about how await behaves. I understand that it pauses execution and waits for the promise to be fulfilled within that context, but how can it truly block execution? Is there something equivalent to threads.join()?

In C++, I would typically create threads to update the database and then join them all at the end before returning from seedDb. What is the correct approach to achieve this in TypeScript?

Using

return await Promise.all(applications.map(async (user) => await prima.user.upsert(...))
(as suggested in a linked StackOverflow question) seems incorrect to me - different functions (seedDb2) could still be running before the promises created by seedDb are finished, which contradicts my goal.

[0] A side inquiry - why use await Promise.all()? Doesn't Promise.all already resolve the promise and return the appropriate type, so why follow it with await again?

Answer №1

In the scenario where you have a function called main() that invokes seedUsers() and seedComments(), with the prerequisite being that users need to be present beforehand.

One approach is to convert your main function into an async function (essentially making it a Promise), utilizing await to ensure that seedUsers() completes its execution before triggering seedComments():

async function seedUsers() {
    let users: Array<Users> = [ ... ];
    // You should return a single Promise either via Promise.all or within the main() function
    return Promise.all(applications.map(async (user) => await prisma.user.upsert(
      { create: user, update: {}, where: { id: user.id } })
    ));
}

async function main() {
  // await halts the execution of the Promise until it is resolved 
  await seedUsers();
  // this will only execute after seedUsers has finished its task
  await seedComments();
}

The reason why your previous code failed was due to using .map within your seedDb() function without returning or utilizing the Promises generated. The role of .map is to transform an array into another format, in this case converting it into Promises, followed by creating a unified Promise through Promise.all that resolves once every promise in the Promise[] array is fulfilled.

For more information, refer to Promises on MDN, which also emphasizes:

Note that JavaScript operates as single-threaded inherently, meaning at any given moment, only one task is running, although control can switch between various promises, giving the illusion of concurrent execution. True parallelism in JavaScript necessitates employing worker threads.

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

Error: 'ngForOf' is not recognized as a valid property of the 'tr' element

Since this afternoon, I've been facing a challenge that I can't seem to grasp. The issue lies within a service I created; in this file, there is an object from which I aim to showcase the data in a loop. An error message is displayed: NG0303: C ...

How can one utilize JSON.parse directly within an HTML file in a Typescript/Angular environment, or alternatively, how to access JSON fields

Unable to find the answer I was looking for, I have decided to pose this question. In order to prevent duplicates in a map, I had to stringify the map key. However, I now need to extract and style the key's fields in an HTML file. Is there a solution ...

onmouseleave event stops triggering after blur event

I am facing an issue with a mouseleave event. Initially, when the page loads, the mouseleave event functions correctly. However, after clicking on the searchBar (click event), and then clicking outside of it (blur event), the mouseleave functionality stops ...

The concept of recursive generics in combination with array inference

I'm struggling to develop a couple of generic recursive types to adjust the structure of existing types. I can't figure out why the sections detecting arrays and nested objects are not being activated. Any thoughts on what might be going wrong? ...

Unidentified Controller Scope in Angular and TypeScript

I am struggling with my Angular 1.5 app that uses Typescript. Here is a snippet of my code: mymodule.module.ts: angular.module('mymodule', []).component('mycomponent', new MyComponent()); mycomponent.component.ts export class MyCont ...

Issues occur during installation of Angular on Mac Catalina, encountering errors while trying to run the installation command for Angular: `% sudo npm

My npm version is 6.14.6 and node version is v12.18.3. I have attempted the following: Added sudo in the beginning, but still not working. Tried to install har-validator using command: sudo npm install har-validator Attempted: npm install --force expo-cli ...

The FaceBook SDK in React Native is providing an incorrect signature when trying to retrieve a token for iOS

After successfully implementing the latest Facebook SDK react-native-fbsdk-next for Android, I am facing issues with its functionality on IOS. I have managed to obtain a token, but when attempting to use it to fetch pages, I keep getting a "wrong signature ...

Is it possible to begin the vue root instance by using a .vue class component?

Utilizing vue-class-component allows me to incorporate class syntax and TypeScript type checking within my .vue files. I can easily create .vue files and register them as components using this method, with the exception of the root Vue() instance. This ap ...

Ways to limit the combination of general types in Typescript?

Struggling to develop a React form component with generic types. The initialValues parameter determines the generic type for the form. Unable to figure out how to specify the type for each field in Typescript. Check out my CodeSandbox where I've at ...

The unit tests are not triggering the execution of setTimeout

Currently, I am developing a project in TypeScript and for unit-tests, I am utilizing QUnit and sinonjs. One of the functions within my code dynamically renders UI elements. I need to retrieve the width of these dynamic elements in order to perform additio ...

The Angular checked functionality is not working as expected due to the presence of ngModel

Just getting started with Angular here. I’m working on a checkbox table that compares to another table and automatically checks if it exists. The functionality is all good, but as soon as I add ngModel to save the changes, the initial check seems to be ...

What is the solution for the error stating "Unable to locate a declaration file for the module 'request-context'."?

I am currently working on three different files: index.js, index.main.js, and app.js. My goal is to use request-context to extract a variable from index.main.js and pass it to index.js. Within my app.js file, located in the server folder, I have the follo ...

Problem with Grouping of Columns in Material-UI

Having some trouble with column grouping in MUI data grid pro. I am using typescript and trying to implement column grouping, but encountering issues with the module GridColumnGroupingModel, which is used as the type definition for columnGroupingModel. Fol ...

I'm having trouble understanding why I can't access the properties of a class within a function that has been passed to an Angular

Currently, I have integrated HTML 5 geolocation into an Angular component: ... export class AngularComponent { ... constructor(private db: DatabaseService) {} // this function is linked to an HTML button logCoords(message, ...

Event for changing Ionic 2 page

Is there a way to execute code every time the page changes without adding an ngOnDestroy method to every page in Ionic 2? Instead of using Ionic 2 page lifecycle hooks like ionViewDidUnload, is there a simpler solution by adding a single method to the mai ...

When evaluating code with eval, properties of undefined cannot be set, but the process works seamlessly without

Currently, I am attempting to utilize the eval() function to dynamically update a variable that must be accessed by path in the format myArray[0][0[1][0].... Strangely enough, when I try this approach, I encounter the following error: Uncaught TypeError: ...

What is causing the error message "Module '@reduxjs/toolkit' or its type declarations are not found" to appear?

Although I have a good understanding of React-Redux, I decided to delve into TypeScript for further practice. Following the recommended approach from the react-redux team, I created a new project using the TS template: "npx degit reduxjs/redux-templa ...

Instructions for setting 0 as a valid value in Html code and displaying it

I have a query regarding HTML code within an Angular app. My inquiry is, is there an alternative method to check for null or undefined values in an ngIf statement? The code I am working with looks like this: <div ngif= "value !== null and value ! ...

Creating a variable as a list of string arrays in TypeScript

Currently working with Angular 2.0, I am trying to declare a variable in a Typescript file that is a list of string arrays. I attempted using yAxis_val: list, but it is not functioning correctly. If anyone knows the proper way to achieve this, please prov ...

The inclusion of HttpClient is causing issues with the functionality of my component

Currently, I am facing an issue with my Angular service called ConnexionService. The problem arises when I try to incorporate CSV files into this service using HttpClient. Strangely, the component associated with this service fails to display once HttpClie ...