Async/Await code not being executes after await - javascript

I have been going over async/await. I trying few simple examples but unable to understand flow of async and await . In below code
function wait(ms) {
return new Promise(r => setTimeout(function() {
console.log('Hello');
}, ms));
}
async function GetUser() {
await wait(5000);
console.log('world');
}
GetUser();
Why is the message "world" not logged? Only "Hello" prints.

You should call the resolver.
function wait(ms) {
return new Promise(r => setTimeout(function(){console.log('Hello'); r();},
// ^^^ this
ms));
}
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

You need to resolve it. So call r()
function wait(ms) {
return new Promise(r => setTimeout(function() {
console.log('Hello');
r()
}, ms));
}
async function GetUser() {
await wait(3000)
console.log('world');
}
GetUser()

Here wait() method returns a Promise, the function of await keyword is to stop code execution until the returned Promise by wait() is resolved.
So the code snippet in question, without using async/await will be as below. Note that the resolve function is not yet invoked here. Hence, once the snippet is executed only Hello will get printed in the console.
// First code snippet
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
}, ms));
}
function GetUser() {
return wait(1000)
.then(() => {
console.log("World")
})
.catch((err) => {
console.log(err);
})
}
GetUser()
Code snippet when r() is invoked. Here, once the snippet is executed Hello and World both are printed in the console.
// Second code snippet
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
r();
}, ms));
}
function GetUser() {
return wait(1000)
.then(() => {
console.log("World")
})
.catch((err) => {
console.log(err);
})
}
GetUser()
The reason why the second code snippet works, has to do with how Promise is implemented in JS.
Handler function/functions attached to a promise with the help of .then() are invoked only when the promise is resolved.
Code snippet when resolve method is not invoked inside the executor function i.e, when the Promise is not resolved. Here, only code inside setTimeout is invoked and not the handlers.
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
}, ms));
}
const promiseReturnedByWaitMethod = wait(2000);
// Multiple handlers can be added to a promise reference, which are executed when the asynchronous operation is completed.
// adding first handler
promiseReturnedByWaitMethod.then(() => {
console.log("First handler!!")
});
// adding second handler
promiseReturnedByWaitMethod.then(() => {
console.log("Second handler!!")
});
Code snippet when resolve method is invoked inside the executor function i.e, when the Promise is resolved.
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
r();
}, ms));
}
const promiseReturnedByWaitMethod = wait(2000);
// Multiple handlers can be added to a promise reference, which are executed when the asynchronous operation is completed.
// adding first handler
promiseReturnedByWaitMethod.then(() => {
console.log("First handler!!")
});
// adding second handler
promiseReturnedByWaitMethod.then(() => {
console.log("Second handler!!")
});

Related

Difference between returning 'fetch(...)' vs returning 'fetch(..).then(...)' [duplicate]

I'm trying to understand difference between these 3. Callbacks & Promises are clear but I don't get the usage of async/await. I know it is the syntactic sugar of promises but what I've tried didn't work. I'm sharing the piece of code I've tried to understand all this...
I've tried with an array
var array = [1,2,3];
and 2 functions
get() executes in 1 sec & console the array
post(item) executes in 2 sec & push a new item in the array
Now, what I want to get is that the post method should execute first & get after it so that the result on the console should be [1,2,3,4] not [1,2,3]
CALLBACK
function get() {
setTimeout(() => console.log(array), 1000);
}
function post(item, callback) {
setTimeout(() => {
array.push(item);
callback();
}, 2000);
}
function init() {
post(4, get);
// returns [1,2,3,4] ✅
}
It works fine but in case of too many callbacks, code will be messier... So,
PROMISE
function get() {
setTimeout(() => console.log(array), 1000);
}
function post(item) {
return new Promise((resolve, reject) => setTimeout(() => {
array.push(item)
resolve();
}, 2000));
}
function init() {
post(4).then(get);
// returns [1,2,3,4] ✅
}
Ok with much cleaner code. But still multiple then calls... Now,
Async/Await
function get() {
setTimeout(() => console.log(array), 1000);
}
function post(item) {
setTimeout(() => {
array.push(item)
}, 2000);
}
async function init() {
await post(4);
get();
// returns [1,2,3] ❌
await post(4);
await get();
// returns [1,2,3] ❌
post(4);
await get();
// returns [1,2,3] ❌
}
Much more cleaner version but neither way, it worked... I've also tried this (convert both functions (post & get) to async and call with then)
async function get() {
setTimeout(() => console.log(array), 1000);
}
async function post(item) {
setTimeout(() => {
array.push(item)
}, 2000);
}
async function init() {
post(4).then(get);
// returns [1,2,3] ❌
}
But still of no use. So I'm totally confused about this feature (i.e. async/await). Please elaborate on this very example. And also please tell me about Promise.resolve & Promise.all in this same context! Thanks
async and await are tools to manage promises
await post(4);
Here you are waiting for the promise returned by post to be resolved.
function post(item) {
setTimeout(() => {
array.push(item)
}, 2000);
}
However, post does not return a promise, so it does nothing useful.
You had a working implementation of post with a promise before. So use that:
function post(item) {
return new Promise((resolve, reject) => setTimeout(() => {
array.push(item)
resolve();
}, 2000));
}
Your attempts with async and await do not use anything that resolves a promise after a delay. As it stands, all the async functions you have defined, return a promise that immediately resolves.
You'll want to use a utility function that you can often use. It returns a promise that resolves after a given number of milliseconds, using setTimeout:
// utility function
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));
let array = [1, 2, 3];
async function get() {
await delay(1000);
console.log(array);
}
async function post(item) {
await delay(1000);
array.push(item)
}
async function init() {
await post(4);
await get();
}
init();
console.log("wait for it...");
Similar to what you did in PROMISE.
Wrap post setTimeout in a promise and return it.
call resolve inside the body of the settimeout.
function post(item) {
return new Promise((resolve)=>{
setTimeout(() => {
array.push(item)
resolve()
}, 2000);
})
}
then you can use it like that :
async function init() {
await post(4);
get();
}

await not doing what I expect

async function doThings() {
async function timer () {
setTimeout(() => {
console.log('timer!')
}), 1000
}
async function printer () {
console.log('printer!')
}
await timer()
await printer()
}
doThings()
I thought making the function async made it return a promise and await made it wait. Why does printer() finish first?
Your timer function doesn't work because setTimeout does not return a promise that could be awaited. You will need to promisify it manually:
// set a default of 1500
function timeout(ms=1500) {
return new Promise(resolve => setTimeout(resolve, ms));
};
async function printer() {
console.log('printer!');
};
async function doThings() {
await timeout(1000); // time in ms
await printer();
};
doThings();
The word “async” before a function means one simple thing: a function always returns a Promise. Other values are wrapped in a resolved Promise automatically.
Now when we use don't return Promise from async function, then javascript interpreter automatically returns resolved Promise, so that is the reason await on timer function got the resolved Promise and interpreter went ahead with the execution, but there is a setTimeout still going on. So we have to return a Promise from timer function, and resolve it inside setTimeout function like below.
async function doThings() {
async function timer() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`timer!`);
resolve();
}, 1000)
});
}
async function printer() {
console.log('printer!')
}
await timer()
await printer()
}
doThings()
All I can see is timer () and printer () functions are async functions but there is no await used in them, and this makes the async keyword unfunctional.

Javascript await a function inside an async function

I have the following codes:
function test1() {
test2.execute();
}
I am trying to use await inside an async function to make test1() execute first:
it("title", async () => {
await test1();
await firebase.assertSucceeds(true);
})
But somehow the function test1() does not execute before firebase.assertSucceeds(true). test1() returns a callback. I tried to use the callback, and it does not help either.
function test1() {
test2.execute().then(() => {
return;
});
}
it("title", async () => {
let x = await test1();
await firebase.assertSucceeds(true);
})
Still synchronous. what did I do wrong here?
In your first snippet you are awaiting for test1 which returns void (nothing), for the await to work it should be applyed to a promise, you acheive that either by returning test2.execute() which returns a Promise :
function test1() {
return test2.execute();
}
or by making test1 async and await for test2 to finish executing :
async function test1() {
await test2.execute();
}
ps: an async function returns a resolved promise with the return as the resolution value so for example :
async function test(){
return 2;
}
is translated under the hood to this:
function test(){
return Promise.resolve(2);
}
A function has to return a Promise if you want to await it.
For example:
function test1() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("I'm done")
}, 500)
})
}
Notice, in the firebase documentation, that assertSucceeds only takes a promise as it's one and only argument. So consider passing it a promise that always resolves if that's what you're going for to begin with.
await firebase.assertSucceeds(Promise.resolve())

Javascript understanding promises

I've been using async with NodeJS, but I'm trying to understand the basic of promises in JavaScript and I'm having issues with it.
I created the code below for testing.
function first() {
// Simulate a code delay
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
}, 500);
});
}
function second() {
console.log(2);
}
first().then(second());
It should print '1' first, but it is printing '2' in the console first. Why is it happening?
Thanks
Two things:
first().then(second()) invokes second() immediately and passes its return value as the argument to then. You want to pass in the function itself, not its return value:
first().then(second); // no parens on second
And you're never resolving the first promise:
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
resolve(); // <-- without this the promise is never resolved
}, 500);
}
);
With those issues addressed it works as you'd intended:
function first() {
// Simulate a code delay
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
resolve(); // <-- without this the promise is never resolved
}, 500);
});
}
function second() {
console.log(2);
}
first().then(second);
There are a 2 problems in your code :
Your function first() returns a promise, but it isn't a promise in itself, so you cannot use the .then attribute on it.
You're not resolving anything in your 1st promise, you're just console.logging something, which is not something you can "wait" for.
What you're looking for is more something like this :
let first = new Promise((resolve) => {
setTimeout( function() {
console.log("1");
resolve(true); //you return your response, for example a boolean
}, 500)
})
function second(){
console.log("2");
}
first.then(response => {
//this is usually where you do something with the response
second();
});
Use Async Await
(as ray write) In new Promise() You must return resolve() or reject()
You can also use await:
function first() {
return new Promise(res => {
console.log(1);
return setTimeout(res, 500);
})
}
function second() {
console.log(2);
}
(async () => {
await first();
second();
})();

Javascript Promise chaining not working as expected

I am trying to return a promise inside a promise but cannot get it to work
Here is my code
async function main() {
return new Promise((resolve, reject) => {
p = new Promise((resolve, reject) => {
f2(async() => {
resolve();
});
});
array = [];
array.push(p);
Promise.all(array).then(resolve(1));
});
}
setTimeout(async() => {
console.log(await main());
}, 0);
function f2(callback) {
console.log("h called");
setTimeout(() => {
callback();
}, 4000);
}
I expect that he array will be resolved after the timeout in f2() but it is resolving instantly.
Any help will be appreciated
The resolve function is being called right away, try something like this:
Promise.all(array).then(() => {
resolve(1);
});
Edit: I wanted to add that what is passed to the then() callback of a promise is a statement, using resolve(1) is a call to execute that code, but by wrapping that function call in an anonymous function declaration, the entire function declaration is passed, and then called when needed.

Categories

Resources