I want to call an async function inside for loop
function test(req,res){
//somelogic part here
async function create(data){
//logic part here
}
for( var value in values){
// some codeing part here
await create(data);
}
}
I want to call an async function inside for loop
function test(req,res){
//somelogic part here
async function create(data){
//logic part here
}
for( var value in values){
// some codeing part here
await create(data);
}
}
I am getting this error
uncaughtException: await is only valid in async function
then I can't call an async function inside For loop. I know it is written like this but is there any possible way I can call an async function inside for loop
for await (var value in values)
Share
Improve this question
edited Jun 29, 2021 at 5:14
asked Jun 29, 2021 at 4:56
user16041868user16041868
2
-
1
put for loop inside
async
function. Also, error clearly states that. It will work inside async only – murli2308 Commented Jun 29, 2021 at 5:23 -
Unless
create
is returning a value I see no reason to useasync/await
here. – Andy Commented Jun 29, 2021 at 5:48
7 Answers
Reset to default 5Hi As I understood your concern I would suggest to use .map() function which is very useful in this type of case.
async function create(data) {
// Create user logic here
}
const usernames = ['test1', 'test2', 'test3'];
const createdUsers = usernames.map(async (val) => {
const user = await create();
return user;
});
await Promise.all(createdUsers);
Just put async
in front of function test.
async function test(req, res) {…
If you want to await
a promise, then the function that's using await
needs to be async
function.
Wrap and create new function inside another function isn't a good ideal. You can move function create to outside like the code bellow
async function create(data){
//logic part here
}
async function test(req,res){
//somelogic part here
for( var value in values){
// some codeing part here
await create(data);
}
}
Or use arrow function instead
async function test(req,res){
//somelogic part here
const create = async (data) => {
//logic part here
}
for( var value in values){
// some codeing part here
await create(data);
}
}
If calling just an asynchronous function is only going to part of your for loop mean you can simple push the promise returned by the asynchronous calls to an array and use promise static methods like 'all'
let pros= []
for(){
pro.push(create(data));
}
Promise.all(pros).then(()=> {
#implement rest or resolve another promise
})
Please refer.. https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
The problem is not with your create
function, but with your test
function. The scope where you call the await
syntax, needs to be async
. Therefore, your scope here is test
.
Simply update your code to the following;
/*vv --> async*/
async function test(req, res) {
console.log("test is called");
async function create(to) {
return new Promise((resolve) => {
setTimeout(() => resolve(Date.now()), to);
});
}
const values = {
a: 1e3,
b: 2e3,
c: 3e3
};
for (var value in values) {
// some codeing part here
const to = values[value];
const result = await create(to);
console.log("result:", result);
}
return 1;
}
(async() => {
const res = await test();
console.log("done");
})();
Your question is a little confusing because there doesn't appear to be any reason to async/await
- create
doesn't appear to return any data so the aync/await
seems redundant, and you can probably remove it.
If, however, create
does return a value, and you want to wait until all the values have been returned before you continue, create an array of function calls and then use Promise.all
to wait until the promises returned from create
have resolved.
// `create` returns a promise that resolves
// after two seconds
function create(data){
return new Promise((res, rej) => {
setTimeout(() => res(data), 2000);
});
}
async function test(req,res) {
const values = [1, 2, 3, 4];
// Create an array of promises
const arr = values.map(el => create(el));
// And use Promise.all to wait to resolve them
const output = await Promise.all(arr);
console.log(output);
}
test();
If you put the Promise
in the for loop
then it will get a total of every responses time in every iteration. So I'm suggesting the Promise.all
for that.
async func() {
let arr = [];
for(var value in values){
arr.push(create(data));
}
let createdArr = await Promise.all(arr);
// Using createdArr, you can get all waited responses
}
In here it will get only the most responding time, not the total. All Promises
run at the same time.