Open baileyparker opened 9 years ago
Not sure. One simple work around is to turn the iterator into an array before passing it into Promise.all.
Right. That's the quickfix I'm using right now. So that it only applies to problematic browsers, I'm using (for others' reference who are experiencing this issue):
var generator = generateSomething(),
nativePromises = Promise.toString().indexOf('[native code]') !== -1,
nativeGenerators = (function() {
try {
eval('(function *() {})');
return true;
} catch(err) {
return false;
}
})();
if(nativePromises && !nativeGenerators) {
generator = Array.from(generator);
}
Promise.all(generator)
// etc ...
But, this isn't very maintainable if generators are being used for lists that would normally be too large to fit comfortably in memory. This is, of course, one of their intended uses. I'll defer to you (Promise pun totally intended), though, @arv about the best way to proceed beyond this band aid solution.
What it comes down to is how much code are you willing to ship to these platforms? It seems like you might want to not use the iterator version of promises if you are planning to do a mobile web app for example.
To enforce this you could do a dev time assert that you are only passing in arrays to Promise.all
.
The Promise polyfill as of 1951203 supports
Promise.all()
on any iterables (including generators compiled by Traceur). This is a great feature!Unfortunately, a problem arises when you try to pass a traceur-compiled generator to a native implementation of
Promise
(notably Safari >=7.1 supports Promises, but not generators). It seems that the nativePromise.all
does not understand Traceur's generators so it silently fails. This is of course very difficult to debug if you don't know what to look for (the Promise never rejects because the input collection is assumed to be empty).Because of the order that browsers supported Generators and Promises, this problem occurs elsewhere:
Promise.all()
would silently fail since the native wouldn't support Traceur's compiled generator (the generator might work in Chrome 38 since that's when it started natively supporting the iteration protocol by default, which is what I assume Traceur compiles generators into)Promise.all()
in Safari will silently failPerhaps Safari >= 7.1 isn't the most important given its small market share, but Chrome 32-39 has about 2.5-3% usage according to CanIUse.com. I think this is a significant enough segment to warrant a fix.
Is the best approach here to polyfill native
Promise.all()
whenever generators are also not native? That feels wrong, but is there another sane way given that Safari >=7.1 doesn't support the new iterator protocol (and nor does Chrome until 38)?