Why await is not waiting - javascript

How to wait for setTimeout to complete first
function a() {
setTimeout(() => {
console.log('should wait');
}, 5000);
}
async function b(c) {
console.log('hello');
await c();
}
b(a);
console.log('out');
My expected output is
Hello
should wait
out

setTimeout does not return a Promise and await only works with Promises.
Also, put the console.log("out") inside the b function for it to run after the a function.
Check the code snippet below, it does what you were looking for.
function a() {
return new Promise((res, rej) => {
setTimeout(() => {
console.log('should wait');
res();
}, 5000);
})
}
async function b(c) {
console.log('hello');
await c();
console.log('out');
}
b(a);

A function must return a promise if you want example to work properly (await keywords "awaits" for returned promise to resolve): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
You example should look like:
function a() {
return new Promise(resolve => {
setTimeout(resolve, 5000);
});
}
async function b(c) {
console.log('hello');
await c();
console.log('should wait');
}
await b(a);
console.log('out');
Note that you can use await keyword on function, because declaring function as async automatically makes it return a 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));
}

How can I return something from the inside of this function (Javascript)?

I have this piece of code which is inside a function that is called by another second function. Now I have no clue, how to return the result to the second function.
(async () => {
try {
const response = await axios.get(knockoutCityURL);
console.log(response.data["1301210"].data.price_overview);
} catch (error) {
console.log(error.response.body);
}
})();
I would be very happy if you could help me.
Remove the IIFE, and just return the Axios promise from a simple function, then make your second function async, and await the data.
(Here's a JSFiddle as async/await doesn't work in a snippet)
function fn1() {
// return axios.get(knockoutCityURL);
return new Promise((res, rej) => {
setTimeout(() => res('Hallo'), 2000);
});
}
async function fn2() {
const data = await fn1();
console.log(data);
}
fn2();

Trying to understand async await

I'm trying to understand why this piece of code doesn't behave as I expect:
async function test() {
await setTimeout(() => {
console.log('done')
}, 1000)
console.log('it finished');
}
test();
This first prints it finished and then prints done afterwards. Shouldn't this code wait for the timeout to finish before executing console.log('it finished'); or have I misunderstood something?
You can only usefully await a promise.
setTimeout returns a timeout id (a number) that you can pass to clearTimeout to cancel it. It doesn't return a promise.
You could wrap setTimeout in a promiseā€¦
async function test() {
await new Promise( resolve => setTimeout(() => {
console.log('done');
resolve("done");
}, 1000));
console.log('it finished');
}
test();

js - How to call an async function within a Promise .then()

First, I have to mention that I already look through many questions in stackoverflow, but many doesn't answer my question. Not to mention many doesn't even have an answer.
How do I achieve the following, making sure functionB() executes after functionA() finishes?
Note: I do not want to convert my async functions to new Promise(resolve=>{...})
because I'll have to convert the someServiceThatMakesHTTPCall() as well, and any other async functions within the call stack, which is a big change.
function functionThatCannotHaveAsyncKeyword() {
functionA()
.then(async function() {
await functionB();
})
.then(function() {
console.log('last');
});
}
async function functionA() {
console.log('first');
await someServiceThatMakesHTTPCall();
}
async function functionB() {
console.log('second');
await someServiceThatMakesHTTPCall();
}
Your approach using await in an async then callback will work, but it's unnecessarily complex if all you want to do is call the async function and have its result propagate through the chain. But if you are doing other things and want the syntax benefit of async functions, that's fine. I'll come back to that in a moment.
async functions returns promises, so you just return the result of calling your function:
function functionThatCannotHaveAsyncKeyword() {
functionA()
.then(function() {
return functionB(someArgument);
})
.then(function() {
console.log('last');
}); // <=== Note: You need a `catch` here, or this function needs
// to return the promise chain to its caller so its caller can
// handle errors
}
If you want to pass functionA's resolution value into functionB, you can do it even more directly:
functionA()
.then(functionB)
// ...
When you return a promise from a then callback, the promise created by the call to then is resolved to the promise you return: it will wait for that other promise to settle, then settle the same way.
Example:
const wait = (duration, ...args) => new Promise(resolve => {
setTimeout(resolve, duration, ...args);
});
async function functionA() {
await wait(500);
return 42;
}
async function functionB() {
await wait(200);
return "answer";
}
functionB()
.then(result => {
console.log(result); // "answer"
return functionA();
})
.then(result => {
console.log(result); // 42
})
.catch(error => {
// ...handle error...
});
Coming back to your approach using an async then callback: That works too, and makes sense when you're doing more stuff:
const wait = (duration, ...args) => new Promise(resolve => {
setTimeout(resolve, duration, ...args);
});
async function functionA() {
await wait(500);
return 42;
}
async function functionB() {
await wait(200);
return "answer";
}
functionB()
.then(async (result) => {
console.log(result); // "answer"
const v = await functionA();
if (v < 60) {
console.log("Waiting 400ms...");
await wait(400);
console.log("Done waiting");
}
console.log(v); // 42
})
.catch(error => {
// ...handle error...
});
You can use promise inside the first method as
function functionThatCannotHaveAsyncKeyword() {
return new Promise(async(resolve, reject)=> {
await functionA();
await functionB();
console.log('last');
resolve();
});
}
async function functionA() {
console.log('first');
await someServiceThatMakesHTTPCall();
}
async function functionB() {
console.log('second');
await someServiceThatMakesHTTPCall();
}
if someServiceThatMakesHTTPCall is async you can avoid all that by doing the following:
function functionThatCannotHaveAsyncKeyword() {
functionA()
.then(function() {
return functionB()
})
.then(function() {
console.log('last');
});
}
function functionA() {
console.log('first');
return someServiceThatMakesHTTPCall();
}
function functionB() {
console.log('second');
return someServiceThatMakesHTTPCall();
}

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');
})();

Categories