Ok lets walk through it. I suspect what's happening is the 0 is actually being spit out on the second pass, so it never gets to the last pass. Which we can verify by reducing the loop size to 2:
Code:
for (i=0;i<2;i++) {
console.log('i='+i);
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve(i), i*100);
promise1.then((successMessage) => {
console.log(successMessage);
});
});
}
Output: 0. So that confirms the first pass is doing nothing. Why? Well lets take the loop out of the equation and think about it:
Code:
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve(i), i*100);
promise1.then((successMessage) => {
console.log(successMessage);
});
});
Output: (nothing, as expected). Is it something weird caused by the setTimeout? Doesn't feel like it, but let's take that out of the equation:
Code:
var promise1 = new Promise(function(resolve, reject) {
resolve(i);
promise1.then((successMessage) => {
console.log(successMessage);
});
});
Output: (still nothing). What's left? Maybe it's something weird in that we're referencing var promise1
inside its own definition. So let's test for with a console.log:
Code:
var promise1 = new Promise(function(resolve, reject) {
resolve(i);
console.log(promise1);
promise1.then((successMessage) => {
console.log(successMessage);
});
});
Output: undefined. So yeah that confirms it. What happens is it's not defined yet the first time through on the loop. On the
second time through it's actually executing the promise1 you defined on the
first time through - hence output: 0. It makes sense that a variable wouldn't be defined yet, until its definition block is done being interpolated by the compiler.
So why doesn't it throw an error on the first pass? Well all I can think of is maybe the Promise constructor swallows exceptions. So let's test for that by wrapping the .then definition in a try/catch block:
Code:
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve(0), 100);
console.log(promise1);
try {
promise1.then((successMessage) => {
console.log(successMessage);
});
}
catch(e) {console.log(e);}
});
Output:
Quote:
TypeError: Cannot read property 'then' of undefined
at VM356 pen.js:7
at new Promise (<anonymous>)
at VM356 pen.js:3
Yep - the Promise constructor is swallowing the exception. Bad Promise constructor. I guess the JS overlords are do as I say, not as I do.
Let's wrap the whole thing in a try/catch block, just on the off chance it's some weird codepen sandbox behavior that's causing the error not to show up:
Code:
try {
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve(i), i* 100);
promise1.then((successMessage) => {
console.log(successMessage);
});
});
}
catch(e) {console.log(e);}
Output: nothing. So yeah, not a weird codepen thing.
So just for fun let's add the loop back in with the try/catch block:
Code:
for (i=0;i<5;i++) {
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve(i), i* 100);
try {
promise1.then((successMessage) => {
console.log(successMessage);
});
}
catch(e) {console.log(e);}
});
}
Output:
Quote:
TypeError: Cannot read property 'then' of undefined
at VM356 pen.js:5
at new Promise (<anonymous>)
at VM356 pen.js:2
0
1
2
3
You can play around with it here:
https://codepen.io/anon/pen/oPdaPm?editors=0012
Really digging codepen over jsFiddle. The only thing you need to make sure to do is change Settings: Behavior to not enable Auto-Updating Preview.
Last edited by suzzer99; 09-13-2018 at 02:13 PM.