Sync iterables and [[asyncIterator]]

# Herbert Vojčík (6 years ago)

Hello!

Lately, I created this in one project:

export async function* zip (...iterables) { for (const iterators = iterables.map(each => (each[Symbol.iterator] || each[Symbol.asyncIterator]).apply(each)); ;) { const all = await Promise.all(iterators.map(async each => await

each.next())); if (all.some(each => each.done)) break; yield all.map(each => each.value); } }

It was sync generator before, but once one of the entries became async generator, I changed the zip itself to be async.

My question is to the pretty ugly

const iterators = iterables.map(each => (each[Symbol.iterator] ||

each[Symbol.asyncIterator]).apply(each))

Is there some more idiomatic way to find "any iterator; sync or async" / alternatively, could sync iterator return respective [[asyncIterator]] as well, just promisifying the result (as a sort of proto-proposal of sort)?

Or is there some easy way to change sync iterable to async iterable, so I could change the other ones at call site?

Thanks,

# Isiah Meadows (6 years ago)

There isn't currently a means to trivially convert them, but sync iterables can still be used in for await. They're implicitly wrapped into an async iterable*, and then used that way.

* That's supposed to be a spec implementation detail, but was accidentally exposed at one point. I recall reading about it somewhere, but I can't easily find it.

# Gus Caplan (6 years ago)

If you use for-await syntax, the js implementation will internally use GetIterator[1] which will look for Symbol.asyncIterator and if it can't find it it will return an async wrapper around Symbol.iterator -Gus [1]: tc39.github.io/ecma262/#sec-getiterator ----

# herby at mailbox.sk (6 years ago)

On August 20, 2018 1:46:45 AM GMT+02:00, Gus Caplan <me at gus.host> wrote:

If you use for-await syntax, the js implementation will internally use GetIterator[1] which will look for Symbol.asyncIterator and if it can't find it it will return an async wrapper around Symbol.iterator -Gus

Would be nice to have something like Reflect.getAsyncIteratorOf(...), then. Or AsyncIterator.of(...), if something like AsyncIterator exists. That would do the wrapping of sync ones as well.