Using promise in a 'for' loop behaves differently on IE11
Ldoppea opened this issue · 2 comments
Hi,
First, thank you for this polyfill. I started to use it 1 year ago and it helps a lot.
I would like to show you a code that behaves differently on chrome/ff/opera and IE11.
This behavior occurs when I use a promise inside a for
loop. When using IE, the for
index is not sent correctly in the promise context.
For example, the following code should loop from 0 to 3 and print the corresponding index.
var sequencer = Promise.resolve();
for (let i = 0; i <= 3; i++) {
sequencer = sequencer.then(function () {
console.log('current index :', i);
});
}
sequencer = sequencer.then(function () {
console.log('end loop');
});
In chrome, each loop occurrence prints the correct index.
Chrome output:
current index : 0
current index : 1
current index : 2
current index : 3
end loop
But in IE, the for
loop ends before the first then
being executed (which is normal behavior) so the index value reached its final value 3
. Then all then
are executed using this final value instead of the "current" value at the moment of their declaration.
IE11 output:
current index : 3
current index : 3
current index : 3
current index : 3
end loop
To fix that, I had to wrap the console.log
inside a function that takes the index
and keep it with its correct value until its execution.
var sequencer = Promise.resolve();
for (let i = 0; i <= 3; i++) {
var next = function (index) {
return function () {
console.log('current index :', index);
};
};
sequencer = sequencer.then(next(i));
}
sequencer = sequencer.then(function () {
console.log('end loop');
});
Chrome output:
current index : 0
current index : 1
current index : 2
current index : 3
end loop
IE11 output:
current index : 0
current index : 1
current index : 2
current index : 3
end loop
As I found a workaround, I'm not blocked by this issue, but it makes the code harder to read.
Also this seems to behave correctly when using array.forEach()
.
Do you know if this may/should be fixed or if this is a limitation from IE11?
Thanks,
Ldoppea
Hi @Ldoppea, unfortunately this does not have to do with promise-polyfill
. This has to do with the keyword let
in the loop. It makes the index value bound in the loop. IE11 does not fully support the let
keyword. I would recommend using a transpiler such as babel
to make this behave as expected.
You can see the same thing issue in the following code. Chrome will work as expected, but IE11 won't.
for (let i = 0; i <= 3; i++) {
setTimeout(function() {
console.log(i);
}, 0);
}
Here is more info about IE11 support for let. You can see it does not support it in loops.
https://kangax.github.io/compat-table/es6/#test-let_for/for-in_loop_iteration_scope
Woups I didn't notice that I was using let
(i'm often switching between old js and modern js), but unfortunately the behavior is the same with var
.
Thank's for your answer, I expected that IE11 was faulty and your answer confirms that 👍