To ensure that execution duration is shorter than interval frequency, I a recursive pattern for the setTimeout
function. But if I combine it with Promise the output "The End" is executed before the loop
ends. How to use Promise correctly, or is Promise the wrong pattern for my needs?
function awaitTimeout(delay) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, delay);
});
}
function loop(msg, i) {
if (i == msg.length) return;
awaitTimeout(200)
.then(function () {
console.log(msg.substring(0, i));
loop(msg, i + 1);
})
.catch();
}
awaitTimeout(3000)
.then(function () {
loop("Hello World, this is a Loop.", 1);
console.log("The End");
})
.catch();
You really only have two problems...
loop
should resolve with the recursively produced promise. It can do so by returning the result of the recursive call.Also, using await
within async
functions typically makes for cleaner code IMO.
const awaitTimeout = (delay) => new Promise((r) => setTimeout(r, delay));
// Async function
const loop = async (msg, i) => {
if (i == msg.length) {
return;
}
await awaitTimeout(20); // shortened for the snippet
console.log(msg.substring(0, i));
return loop(msg, i + 1); // return the recursive result
};
awaitTimeout(0) // shortened for the snippet
.then(() => loop("Hello World, this is a Loop.", 1))
.then(() => { // wait for it all to complete
console.log("The End");
});
Without using async
functions, loop
would look like this
const loop = (msg, i) => {
if (i == msg.length) {
return;
}
return awaitTimeout(200).then(() => { // return a promise
console.log(msg.substring(0, i));
return loop(msg, i + 1); // return the result
});
};