Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript async await doesn't work inside forEach loop

I have few queries to a database which I want to gather into a transaction.

let t = await db.sequelize.transaction()
  try {
    let adr = await addressRepo.add(address, t)
    let user = await userRepo.add(email, password, name, surname, phone, NIP, REGON, id_number, adr.id, t)
    await userRoleRepo.add(user.id, user_role, t)
    if (languages != null) {
      languages.forEach(async function (language) {
        await userLanguageRepo.add(user.id, language.id, language.main, t)
      })
    }
    await t.commit()
    res.status(201).json(user)
  } catch (error) {
    await t.rollback()
}

According to above code, the transaction is created and all queries are included except of those in forEach loop. As a result I get:

Executing (fb270893-9146-43b7-a35e-8960ea386513): START TRANSACTION;
Executing (fb270893-9146-43b7-a35e-8960ea386513): INSERT INTO `address` (`id`,`country`) VALUES (DEFAULT,'country');
Executing (fb270893-9146-43b7-a35e-8960ea386513): INSERT INTO `user` (`id`,`email`,`password`,`name`,`surname`,`active`,`address_id`,`created_at`,`updated_at`) VALUES (DEFAULT,'a15','$2a$10$7uImQNl0T12CZLUB0Asxwu8yCGUa/eZnbr8TATX8V/tnnO8erdYzy','John','Dee','0',15,'2017-08-28 07:44:03','2017-08-28 07:44:03');
Executing (fb270893-9146-43b7-a35e-8960ea386513): INSERT INTO `user_role` (`user_id`,`role_id`) VALUES (7,1);
Executing (fb270893-9146-43b7-a35e-8960ea386513): COMMIT;
(node:5873) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: commit has been called on this transaction(fb270893-9146-43b7-a35e-8960ea386513), you can no longer use it. (The rejected query is attached as the 'sql' property of this error)
(node:5873) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:5873) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: commit has been called on this transaction(fb270893-9146-43b7-a35e-8960ea386513), you can no longer use it. (The rejected query is attached as the 'sql' property of this error)

I looked at async commit is execute before forEach loop. How can I execute forEach loop before commit?

like image 691
trojek Avatar asked Aug 28 '17 07:08

trojek


People also ask

Can async-await be used inside forEach?

forEach is not designed for asynchronous code. (It was not suitable for promises, and it is not suitable for async-await.) For example, the following forEach loop might not do what it appears to do: const players = await this.

Why async does not work in forEach?

forEach method only accepts a synchronous function, and therefore is NOT compatible with the async/await syntax. Instead, you can use the for … of iterator as per below which is compatible with the async/await syntax.

Can await be used in forEach?

forEach() method to run asynchronous code. Programmers use the forEach method to loop through each of the elements of an array to execute the same process. Unfortunately, the forEach method wasn't meant to execute asynchronous callback functions, even though it is possible to use the keywords async and await with it.

Can I use async-await in loop JavaScript?

You need to place the loop in an async function, then you can use await and the loop stops the iteration until the promise we're awaiting resolves. You could also use while or do.. while or for loops too with this same structure.


1 Answers

Instead of forEach one should use for of loop.

I found the answer at this post.

like image 108
trojek Avatar answered Oct 13 '22 03:10

trojek