You simply forgot to tell javascript to "await" for that timeout between each iteration of the for loop. So what's happening it that javascript will run the for loop, schedule three timeouts while doing so, then those three timeouts all go off at once.
If you add an await like so, then it'll work as you expected.
(async function() {
let arr = [1, 2, 3];
for (let x of arr) {
await (function() { // <-- await added
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("111")
resolve(true)
}, 3000);
})
})()
.then(() => {
console.log("222")
})
}
})()
I switched to for-of, because .forEach() doesn't work with async functions. I also wrapped the whole thing inside an async IIFE because a top-level await wasn't allowed there - depending on where you put this code, you might not have to wrap it inside an async IIFE.
EDIT
Just realized, you didn't use async/await stuff anywhere in your original question. I don't know if you've learned about it yet but you don't have to know it to solve this particular problem.
Here's another way to do it without async/await.
let arr = [1, 2, 3];
let promise = Promise.resolve();
arr.forEach((x,i) => {
promise = promise
.then(function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("111")
resolve(true)
}, 3000);
})
})
.then(() => {
console.log("222")
})
});
This is basically building a promise chain inside the loop. If you "unwound" the loop, it would look like this:
promise = Promise.resolve()
promise = promise
.then(() => /* wait 3000 ms and log "111" */)
.then(() => { console.log("222") })
.then(() => /* wait 3000 ms and log "111" */)
.then(() => { console.log("222") })
.then(() => /* wait 3000 ms and log "111" */)
.then(() => { console.log("222") })
Because we're keeping around the a reference to the last promise, and we keep tacking onto the end of it, each new thing we tack on will happen after the last thing gets completed.