JS: awaiting promises in map [duplicate] - javascript

This question already has answers here:
Resolve promises one after another (i.e. in sequence)?
(36 answers)
Is Node.js native Promise.all processing in parallel or sequentially?
(14 answers)
Closed 6 months ago.
I asked a question that was closed due to similar questions but even after reading those and seeing that map is not Promise aware, I have tried to use await Promise.all() around my mapping.
let foo = [1,2,3];
(async() => {
await Promise.all(foo.map(x => {
return new Promise(async function(resolve) {
await setTimeout(() => {
console.log("X")
resolve()
}, 3000)
});
}))
})()
instead of sequentially getting a "X" log every 3 seconds, it's just waiting 3 seconds and then logging them all. I am not sure what I am doing wrong at this point.

You are setting all the timeouts together at once. You need to increase the timeout duration in each iteration, maybe like this:
let foo = [1,2,3];
(async() => {
await Promise.all(foo.map((x, i) => {
return new Promise(async function(resolve) {
await setTimeout(() => {
console.log("X")
resolve()
}, 3000 * (i + 1))
});
}))
})()

Related

JS - Why code does not run after async / await for promise [duplicate]

This question already has answers here:
Why does nodejs stop execution of while true loop inside async function
(3 answers)
Closed 28 days ago.
I have a sample code on TS playground represents my problem.
In an async function, I log the result after await for the promise, but only the code inside promise run, not the log outside of it. Could someone explain this problem?
Here is the code:
const asyncFnc = async () => {
let result = false;
await new Promise(resolve => {
setTimeout(() => {
// This log worked
console.log('waited 5s');
result = true;
}, 5000);
});
// This log did not worked
console.log(result);
}
asyncFnc();
And the result:
await sends the parent function to sleep until the promise on the right hand side settles (i.e. resolves or rejects).
Your promise never resolves or rejects. (i.e. you don't call resolve, make use of the second argument, or throw an exception).
Thus the parent function sleeps forever.
The idiomatic way to write this would be to avoid setting variables in the wider scope as a side effect, and just resolve with the values instead.
const asyncFnc = async () => {
const result = await new Promise(resolve => {
setTimeout(() => {
console.log('waited 5s');
resolve(true);
}, 5000);
});
console.log(result);
}
asyncFnc();
You need to call resolve() in your timeout

Javascript is not returning objects as expected [duplicate]

This question already has answers here:
Why do I need to await an async function when it is not supposedly returning a Promise?
(3 answers)
async/await implicitly returns promise?
(5 answers)
async function - await not waiting for promise
(5 answers)
async/await always returns promise
(4 answers)
Closed 5 months ago.
Javascript (or Node.js) is not returning objects as expected.
The following code logs an empty array.
const _sodium = require('libsodium-wrappers');
const sodium = (async () => {
await _sodium.ready;
return _sodium;
})();
console.log(Object.getOwnPropertyNames(sodium));
On the other hand, the following code works as expected.
const _sodium = require('libsodium-wrappers');
(async () => {
await _sodium.ready;
const sodium = _sodium;
console.log(Object.getOwnPropertyNames(sodium));
})();
In the first code snippet, it seems like the sodium object is tied to its lexical environment, which would explain why an empty array is printed. I would be interested in what's going on here (including an explanation of what's going on under the hood). Thanks.
It's not about lexical context.
You just not awaiting for ready in the first example.
First example simplified:
(async() => {
console.log('start')
await new Promise(r => setTimeout(r, 3000))
console.log('finish')
})()
Second example simplified:
console.log('start');
(async() => {
await new Promise(r => setTimeout(r, 3000))
})();
console.log('finish')

Why promise fires function immediately? [duplicate]

This question already has answers here:
When is the body of a Promise executed?
(4 answers)
Why do promises execute at the point of declaration?
(2 answers)
Why does my Promise definition gets executed?
(2 answers)
Is the Promise constructor callback executed asynchronously?
(2 answers)
Closed 8 months ago.
I can't get why function in new Promise fires immediately. Shouldn't it be put in Microtask queue and fire after all global code has executed?
Code:
const prom = new Promise((resolve, reject) => {
console.log("in Promise");
resolve(20);
});
prom.then((data) => {
console.log(12312323);
console.log(data);
});
console.log(77);
Link to code
Output:
in Promise
77
12312323
20
When you construct a Promise, its task begins execution immediately.
const p = new Promise((resolve) => {
console.log('in promise');
resolve("value");
})
Promises are primarily useful for asynchronous tasks like network requests, and their delayed resolution can make it seem like the execution itself has been deferred, but that's not what's happening.
In this example you can see that there can be a significant delay between when the task starts and when the promise is resolved:
const p = new Promise((resolve) => {
console.log('first: in promise'); // first
setTimeout(() => resolve('resolved value'), 2000) // wait 2 seconds before resolving.
})
p.then(val => console.log(`third: ${val}`)); // third
console.log("second: after p.then"); // second

Use await only for 20 seconds [duplicate]

This question already has answers here:
NodeJS Timeout a Promise if failed to complete in time
(8 answers)
Closed 2 years ago.
I am waiting for my promise to resolve in an async function using await but I want to wait for only 20 sec. If no response comes in that time (neither positive nor negative from the promise), I want to continue and display 'timeout'. How can I do this?
You can use Promise.race:
const promise1 = func();
const promise2 = new Promise((res, rej) => setTimeout(rej, 20000));
try {
await Promise.race([promise1, promise2]);
} catch (e) {
// time out or func failed
}

How to create a synchronized loop with async/wait [duplicate]

This question already has answers here:
Using async/await with a forEach loop
(33 answers)
Closed 5 years ago.
I'm trying to create a "synchronized like loop" with async await but I get the strange behavior of getting all the results after the first promise instead.
here is my test case. See how you get all together instead of print 1 by 1
const p = () => new Promise((resolve) =>{
setTimeout(()=>{
resolve(Math.floor(Date.now() / 1000))
},1000)
})
const test = () =>{
[1,2,3,4,5,6,7,8,9,10].map(async () =>{
const e = await p();
console.log(e)
});
}
test();
Like I mention in comments, map is not Promise aware. There are alternatives like Bluebirds.map,.. But the easy option is to use a for loop,..
Keeping to your example were your wanting to loop an array, you can use the for of variant too. Changing to for (let a = 1; a <= 10; a ++) will work too.
eg.
const p = () => new Promise((resolve) =>{
setTimeout(()=>{
resolve(Math.floor(Date.now() / 1000))
},1000)
})
const test = async () =>{
for (const a of [1,2,3,4,5,6,7,8,9,10]) {
const e = await p();
console.log(e)
}
}
test();
It's also worth pointing out bluebirds map has another trick up it's sleeve, it has a concurrency option. This is very handy to prevent thrashing that can happen with Promise.all, you basically say you want to do x promises at a time, eg. you have 10 promises to do, but you find it's more optimal to do 3 concurrently.

Categories