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();
}
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.
Async/Await is used to work with promises in asynchronous functions. It is basically syntactic sugar for promises. It is just a wrapper to restyle code and make promises easier to read and use. It makes asynchronous code look more like synchronous/procedural code, which is easier to understand.
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 you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With