cujojs / when

A solid, fast Promises/A+ and when() implementation, plus other async goodies.
Other
3.44k stars 396 forks source link

Support iterables #364

Open briancavalier opened 10 years ago

briancavalier commented 10 years ago

The ES6 spec for all and race says they accept an ES6 iterable. We should support iterables in all the collection methods. Not all platforms support iterables yet, and the ones that do support them to different degrees and use different names/symbols to access iterators, eg FF uses @@iterator, node uses iterator (does any platform implement Symbol yet??). So, we'll probably have to use some helpers (like the ones we use in most.js to access iterators, since we won't be able to rely on for of for a while.

dthorpe commented 10 years ago

Symbol is available in the node v0.11.13 release (and earlier v.0.11.*) with --harmony.

briancavalier commented 10 years ago

@dthorpe cool, thanks for the tip!

natew commented 9 years ago

:+1:

Just ran into this using immutable-js: https://github.com/facebook/immutable-js/issues/236#issuecomment-66586995

briancavalier commented 9 years ago

Thanks @natew. I'll put this on the slate for 3.7.0. It'd be great to play nice with immutable-js, and as ES6 gets closer, supporting iterables will become more and more critical.

briancavalier commented 9 years ago

I whipped up a quick strawman in the add-iterable-support branch. It adds iterable support in when.all/Promise.all, and when.map. I also created a quick and dirty test program that tests it against a custom ArrayIterable.

There's virtually no perf difference, which is nice. Unfortunately, the strawman duplicates more code than I'd like in traverse in lib/makePromise (which is used for both all and map). It's good to have some code to look at though, and I'm sure there are ways to slim it down a bit. Size-wise, it adds about 100 gzip+minified bytes.

We'd need to do something similar for race.

briancavalier commented 9 years ago

More progress in the add-iterable-support branch. Both all and race support iterables. However, I had to (maybe temporarily) drop support for sparse arrays. The approach I've taken is to wrap Arrays in a simple iterator, and just deal with iterators internally. There is a small perf hit for all(array) and race(array) now, with the upside that iterables actually work, and are quite fast (it depends on the speed of the particular iterator, of course). The way in which all is coded means that map will also work with iterables (with the same sparse Array caveat).

We'd probably need to extend this further to any and some (although some is deprecated, so maybe just any).

Care to try it out, @natew ?

natew commented 9 years ago

If I get a chance, unfortunately I ran into this while working on a project with a deadline looming, so I switched to bluebird and have made some progress since then. I think setting up a test case would be pretty easy though with immutable. If I get some time I'll try and squeeze it in.