Basically I am trying to play around to understand more of async/await
and promise
in JS
. I'm trying to make Hello comes in between finished! and third finish!!. So the best guess is, making second then
asnyc and await for console.log('Hello')
. I've tried both ways below but both are not working as expected.
Approach A
let promise = new Promise((res,rej)=>{
res();
});
promise.then(() => {
console.log('finished!')
}).then(() => {
setTimeout(async function(){
await console.log("Hello"); }, 3000); //async/await at setTimeout level
}).then(() => {
console.log('third finish!!')
})
Approach B:
let promise = new Promise((res,rej)=>{
res();
});
promise.then(() => {
console.log('finished!')
}).then(async () => { //async/await at thenlevel
await setTimeout(function(){
console.log("Hello"); }, 3000);
}).then(() => {
console.log('third finish!!')
})
You need the second section to be a Promise
, and return it from the .then
so that it's properly chained between the first and the third. setTimeout
doesn't return a Promise
, you have to explicitly construct a Promise
instead:
let promise = new Promise((res,rej)=>{
res();
});
promise.then(() => {
console.log('finished!')
}).then(() => {
return new Promise(resolve => {
setTimeout(function(){
console.log("Hello");
resolve();
}, 1000);
});
}).then(() => {
console.log('third finish!!')
})
Or, using await
, use await new Promise
followed by the same Promise construction and the setTimeout
:
let promise = new Promise((res, rej) => {
res();
});
promise.then(() => {
console.log('finished!')
}).then(async() => {
await new Promise(resolve => {
setTimeout(function() {
console.log("Hello");
resolve();
}, 1000);
});
}).then(() => {
console.log('third finish!!')
})
Another approach is to write an asynchronous setAsyncTimeout
function (this hasn't been thoroughly tested, may need tweaks):
async function setAsyncTimeout(callback, interval) {
return new Promise( (resolve, reject) => {
setTimeout(() => {
try {
let inner = callback()
if (inner && inner.then) {
inner.then(resolve, reject)
} else {
resolve(inner)
}
} catch(e) {
reject(e)
}
}, interval)
})
}
Testing via your example:
let promise = new Promise((res,rej)=>{
res();
});
promise.then(() => {
console.log('finished!')
}).then( setAsyncTimeout(function(){
console.log("Hello"); }, 3000);
}).then(() => {
console.log('third finish!!')
})
Testing via your example (with another promise):
let promise = new Promise((res,rej)=>{
res();
});
promise.then(() => {
console.log('finished!')
}).then(async () => { //async/await at thenlevel
await setAsyncTimeout(function(){
console.log("Hello");
return setAsyncTimeout(() => console.log("world"), 3000)
}, 3000);
}).then(() => {
console.log('third finish!!')
})
Cleaner example:
let promise = new Promise((res,rej)=>{
res();
});
promise.then(() => {
console.log('finished!')
}).then(() => {
return setAsyncTimeout(() => { console.log("Hello"); }, 3000)
}).then(() => {
console.log('third finish!!')
})