Wha does synchronous usage of setTimeout stops the code if using await? - javascript

The following code brings just
"before timeout" and "within"
but not "after timeout".
why is this ?
async function asy() {
console.log('before timeout');
await awa();
console.log('after timeout');
}
async function awa() {
return new Promise(resolve => {setTimeout(function(){console.log('within');}, 600);
}
asy();

Because you are never resolving the promise, so it's hanging forever.
return new Promise(resolve => {setTimeout(function(){console.log('within');}, 600);
^^^^^^^
NEVER USED

You haven't resolved the Promise after returning and hence the output
async function asy() {
console.log('before timeout');
await awa();
console.log('after timeout');
}
async function awa() {
return new Promise(resolve => {
setTimeout(function(){
console.log('within');
resolve();
}, 600);
}
asy();
await waits till the Promise is resolved or rejected before executing the following expressions

you don't need the async before the function awa():
async function asy() {
console.log('before timeout');
await awa();
console.log('after timeout');
}
function awa() {
return new Promise(
resolve => {
setTimeout(function(){console.log('within'); resolve();}, 600);
});
}
asy();

Resolve the promise
this.driverWait = async function (explicitWaitMS) {
// create a new promise inside of the async function
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(true), explicitWaitMS) // resolve
});
// wait for the promise to resolve
await promise;
}

Related

I am finding it hard to understand why the code after await does not execute

async function setTime() {
await new Promise(resolve => setTimeout(()=>{console.log("my func is fine")}, 5000));
}
async function realFunction() {
await setTime();
console.log("second call!");
}
In the above code, when i call realFunction, it logs my func is fine, but it does not log second call. Can someone help me understand what am I doing wrong, and how can I get the statement to be logged?
Because you never resolver your promise. You always need to resolve or reject it.
Also async / await is pretty much useless for setTime
function setTime(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
async function realFunction() {
await setTime(5000);
console.log("second call!");
}
The prolbem is that you never resolve the Promise so it's pending forever.
Try to change it like this:
async function setTime() {
await new Promise((resolve) =>
setTimeout(() => {
console.log('my func is fine');
resolve();
}, 5000)
);
}
async function realFunction() {
await setTime();
console.log('second call!');
}
You need to resolve the promise, and for that you can call resolve()
So your setTime() function would look like this:
async function setTime() {
await new Promise(resolve => setTimeout(()=>{
console.log("my func is fine")
return resolve();
}, 5000));
}

Await doesnt seem to work for arrow function? [duplicate]

To understand async/await, I am trying to display a console message once settimeout runs and expires. How do I fix my code below? I have 5 settimeout function and each should display respective message once finished.
function t1(){
setTimeout(() => {
console.log("1")
}, 1000);
}
function t2(){
setTimeout(() => {
console.log("2")
}, 2000);
}
function t3(){
setTimeout(() => {
console.log("3")
}, 3000);
}
function t4(){
setTimeout(() => {
console.log("4")
}, 4000);
}
function t5(){
setTimeout(() => {
console.log("5")
}, 5000);
}
async function main(){
await t1();
console.log("1sec done");
await t2();
console.log("2sec done");
await t3();
console.log("3sec done");
await t4();
console.log("4sec done");
await t5();
console.log("Yay! I am all done");
}
main();
You should use Promises
function t1(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("1");
resolve();
}, 1000);
});
}
function t2(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("2");
resolve();
}, 1000);
});
}
function t3(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("3");
resolve();
}, 1000);
});
}
function t4(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("4");
resolve();
}, 1000);
});
}
function t5(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("5");
resolve();
}, 1000);
});
}
async function main(){
await t1();
console.log("1sec done");
await t2();
console.log("2sec done");
await t3();
console.log("3sec done");
await t4();
console.log("4sec done");
await t5();
console.log("Yay! I am all done");
}
main();
You are doing two mistakes
First you are using await before a calling a function t1,t2,t3.... await should be used on Promises.
You are passing 1000,2000,... to setTimeout(). You should create a function which returns a Promise which will be resolved after 1 second
Use await before the promise returned by that function
let afterOne = (num) => new Promise(res => {
setTimeout(()=>{
//log the number passed to function after 1000 ms
console.log(num);
//resolve the current promise so then next setTimeout could be set
res();
},1000)
})
async function main(){
/*This loop does same as
await afterOne(0);
await afterOne(1);
await afterOne(2)
await afterOne(3);
await afterOne(4);
*/
for(let i = 0;i<5;i++){
await afterOne(i)
}
}
main();
For each of the functions t1() through t5(), you'll need to ensure these return a Promise such that the returned promise is "resolved" once the respective setTimeout() timer inside has completed.
By returning the Promise object in this way, your t1() -> t5() functions effectivly become async methods, which in turn means than the await prefix will cause execution of main() to block until each t1() -> t5() function has completed (or "been resolved").
To illustrate this, consider the following code where a generic delay() function replaces the t1() -> t5() functions in your original code:
/* I've defined a generic delay function as replacement
for t1 - t5 functions to minimise the amount of code */
function delay(seconds) {
/* Return a promise object that will cause the
await to prevent main() async function's execution
from continuing until this promise has resolved */
return (new Promise((resolve) => {
/* Inside the promise, set your time out */
setTimeout(() => {
console.log(seconds)
/* When time out complete, call resolve(), which
resolves this promise and allows main() async
function's execution to continue */
resolve()
}, seconds * 1000);
}))
}
async function main() {
await delay(1);
console.log("1sec done");
await delay(2);
console.log("2sec done");
await delay(3);
console.log("3sec done");
await delay(4);
console.log("4sec done");
await delay(5);
console.log("Yay! I am all done");
}
main();

Using Async/Await on multiple settimeout

To understand async/await, I am trying to display a console message once settimeout runs and expires. How do I fix my code below? I have 5 settimeout function and each should display respective message once finished.
function t1(){
setTimeout(() => {
console.log("1")
}, 1000);
}
function t2(){
setTimeout(() => {
console.log("2")
}, 2000);
}
function t3(){
setTimeout(() => {
console.log("3")
}, 3000);
}
function t4(){
setTimeout(() => {
console.log("4")
}, 4000);
}
function t5(){
setTimeout(() => {
console.log("5")
}, 5000);
}
async function main(){
await t1();
console.log("1sec done");
await t2();
console.log("2sec done");
await t3();
console.log("3sec done");
await t4();
console.log("4sec done");
await t5();
console.log("Yay! I am all done");
}
main();
You should use Promises
function t1(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("1");
resolve();
}, 1000);
});
}
function t2(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("2");
resolve();
}, 1000);
});
}
function t3(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("3");
resolve();
}, 1000);
});
}
function t4(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("4");
resolve();
}, 1000);
});
}
function t5(){
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log("5");
resolve();
}, 1000);
});
}
async function main(){
await t1();
console.log("1sec done");
await t2();
console.log("2sec done");
await t3();
console.log("3sec done");
await t4();
console.log("4sec done");
await t5();
console.log("Yay! I am all done");
}
main();
You are doing two mistakes
First you are using await before a calling a function t1,t2,t3.... await should be used on Promises.
You are passing 1000,2000,... to setTimeout(). You should create a function which returns a Promise which will be resolved after 1 second
Use await before the promise returned by that function
let afterOne = (num) => new Promise(res => {
setTimeout(()=>{
//log the number passed to function after 1000 ms
console.log(num);
//resolve the current promise so then next setTimeout could be set
res();
},1000)
})
async function main(){
/*This loop does same as
await afterOne(0);
await afterOne(1);
await afterOne(2)
await afterOne(3);
await afterOne(4);
*/
for(let i = 0;i<5;i++){
await afterOne(i)
}
}
main();
For each of the functions t1() through t5(), you'll need to ensure these return a Promise such that the returned promise is "resolved" once the respective setTimeout() timer inside has completed.
By returning the Promise object in this way, your t1() -> t5() functions effectivly become async methods, which in turn means than the await prefix will cause execution of main() to block until each t1() -> t5() function has completed (or "been resolved").
To illustrate this, consider the following code where a generic delay() function replaces the t1() -> t5() functions in your original code:
/* I've defined a generic delay function as replacement
for t1 - t5 functions to minimise the amount of code */
function delay(seconds) {
/* Return a promise object that will cause the
await to prevent main() async function's execution
from continuing until this promise has resolved */
return (new Promise((resolve) => {
/* Inside the promise, set your time out */
setTimeout(() => {
console.log(seconds)
/* When time out complete, call resolve(), which
resolves this promise and allows main() async
function's execution to continue */
resolve()
}, seconds * 1000);
}))
}
async function main() {
await delay(1);
console.log("1sec done");
await delay(2);
console.log("2sec done");
await delay(3);
console.log("3sec done");
await delay(4);
console.log("4sec done");
await delay(5);
console.log("Yay! I am all done");
}
main();

Understanding Promise and Await

I am just trying to understand how Promises and Async-Await work.
I want this to resolve by logging 1, 2, 3 in that order. Currently it logs 1, 3, 2.
I know the Promise doesn't really make sense here but in my program it has other uses so that needs to stay. The route from Caller function to Test also needs to stay (If need be you can change these but just know that they are there for a reason)
My question is how do I wait for the Caller function to resolve?
Here is my code:
function Test() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('2');
resolve();
}, 2000);
})
}
function Caller() {
Test();
}
console.log('1');
Caller();
console.log('3');
I have tried what I understand, which is to make the Caller() function await the Test Promise, but that of course makes the Caller() function async and therefore we still get 1, 3, 2
async function Caller() {
await Test();
}
Is there maybe some way to use await without making the function async?
You can only await a function that returns a promise (well, not quite true, if it doesn't return a promise it creates a promise that resolves instantly)
You can only await when you are inside an asynchronous function
function test() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('2');
resolve();
}, 2000);
})
}
async function caller() {
console.log('1');
await test();
console.log('3 (this is blocked awaiting the promise');
}
caller()
console.log("This is not blocked because caller is async");
This is a very straightforward, simple way of doing what you ask.
The await keyword can only be used inside functions
defined with async.
function test(ms) {
return new Promise((resolve, reject) => setTimeout(resolve, ms))
}
async function caller() {
console.log(1, ' - caller() started');
await test(2000).then(() => {
console.log(2, ' - test() resolved')
});
console.log(3, ' - delayed until "test()" has resolved');
return 4;
}
// wait for "caller()" to resolve
caller().then((result) => {
console.log(result, " - caller() finished")
});
console.log(5);
Here's a good article by Google which expands on the subject:
Async functions - making promises friendly.
Cite source.
here is how you could use functions like this:
function sleep(ms) {
return new Promise(r => {
setTimeout(() => r(), ms);
});
}
(async () => {
console.log(1);
await sleep(1000); // 1s
console.log(2);
await sleep(2000) // 2s
console.log(3)
})();
The previous answers are all correct but I just feel like this answer makes more sense. It is more accurate to the original question's code:
function Test() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('2');
resolve();
}, 2000);
})
}
function Caller() {
return Test();
}
(async() => {
console.log('1');
await Caller();
console.log('3');
})();

Javascript Promise with Await Explanation

I would just like to understand how promises and await work together. Look at the following code:
console.log("One: Started");
setTimeout(function(){console.log("One: Completed")}, 1000);
console.log("Two: Started");
setTimeout(function(){console.log("Two: Completed")}, 2000);
console.log("Three: Started");
setTimeout(function(){console.log("Three: Completed")}, 3000);
So this of course logs:
One: Started
Two: Started
Three: Started
One: Completed
Two: Completed
Three: Completed
I would like to have the one complete before the next one starts. I wrote this with my understanding of promises and await but this is not working. Would someone please try and edit this code to get it working. And please and an explanation as I am trying to understand promises and await
async function LogAll() {
console.log("One: Started");
await function() {
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log("One: Completed");
resolve();
}, 1000);
});
}
console.log("Two: Started");
await function() {
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log("Two: Completed");
resolve();
}, 2000);
});
}
console.log("Three: Started");
await function() {
return new Promise((resolve, reject) => {
setTimeout(function(){
console.log("Three: Completed");
resolve();
}, 3000);
});
}
}
LogAll();
You need to await promises, not functions alone. When you await function ... (without calling it), the function is evaluated as an expression and then discarded. Just call the functions:
async function LogAll() {
console.log("One: Started");
await (function() {
return new Promise((resolve, reject) => {
setTimeout(function() {
console.log("One: Completed");
resolve();
}, 1000);
});
})();
console.log("Two: Started");
await (function() {
return new Promise((resolve, reject) => {
setTimeout(function() {
console.log("Two: Completed");
resolve();
}, 2000);
});
})();
console.log("Three: Started");
await (function() {
return new Promise((resolve, reject) => {
setTimeout(function() {
console.log("Three: Completed");
resolve();
}, 3000);
});
})();
}
LogAll();
Or, for this example, don't use functions at all - just await the promises directly:
async function LogAll() {
console.log("One: Started");
await new Promise((resolve, reject) => {
setTimeout(function() {
console.log("One: Completed");
resolve();
}, 1000);
});
console.log("Two: Started");
await new Promise((resolve, reject) => {
setTimeout(function() {
console.log("Two: Completed");
resolve();
}, 2000);
});
console.log("Three: Started");
await new Promise((resolve, reject) => {
setTimeout(function() {
console.log("Three: Completed");
resolve();
}, 3000);
});
}
LogAll();
The async function declaration defines an asynchronous function, which returns an AsyncFunction object.
An async function can contain an await expression that pauses the execution of the async function and waits for the passed Promise's resolution, and then resumes the async function's execution and returns the resolved value.
function resolveAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('calling');
}, 2000);
});
}
async function asyncCall() {
var result = await resolveAfter2Seconds();
console.log(result);
// expected output: "resolved"
console.log('called');
}
asyncCall();
For More refer Async Await
What is an async Function:
It is a function which returns a AsyncFunction Object, similar to Promises. If it throws an error, the object rejects, otherwise when it returns a value, it resolves.
Async Functions are newer and before they existed there were different ways to write asynchronous code: Promises (part of rxjs), Observables ("infinite Promises"), callbacks used with timing events.
What is the await keyword:
In Javascript the await keyword can only be used inside an async Function with the following syntax:
[returnValue] = await expression;
Where the expression can be a Promise or any other value returned by asynchronous code.
await tells the code to stop and wait for that value.
Without that, the returnValue in the above expression would be immediately given a value (undefined most probably) and the code will continue without blocking. After some unknown time and unknown point in the code, the function will finally return and returnValue will finally receive the correct value. But maybe the code went forward and wrongly assumed you already had a defined and updated value, possibly failing.
Try to run the snippets without async await. They are counter examples to show the corresponding synchronous code:
EXAMPLE 1: all Promises are started immediately
function LogAll() {
console.log("One: Started");
new Promise((resolve, reject) => {
setTimeout(function() {
console.log("One: Completed");
resolve();
}, 1000);
});
console.log("Two: Started");
new Promise((resolve, reject) => {
setTimeout(function() {
console.log("Two: Completed");
resolve();
}, 2000);
});
console.log("Three: Started");
new Promise((resolve, reject) => {
setTimeout(function() {
console.log("Three: Completed");
resolve();
}, 3000);
});
}
LogAll();
EXAMPLE 2: No promises at all (identical results to example 1)
function LogAll() {
console.log("One: Started");
setTimeout(function() {
console.log("One: Completed");
}, 1000);
console.log("Two: Started");
setTimeout(function() {
console.log("Two: Completed");
}, 2000);
console.log("Three: Started");
setTimeout(function() {
console.log("Three: Completed");
}, 3000);
}
LogAll();
In Example 2 please note that setTimeout is a timing event, an older feature of Javascript, so it does not really need a wrapper Promise, except the Promise allows you to throw errors and reject.

Categories