microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.75k stars 12.46k forks source link

Needs Proposal: Async Iterators. #12755

Closed benjamingr closed 7 years ago

benjamingr commented 7 years ago

Async Iterators

Async iterators is a stage 3 proposal: https://github.com/tc39/proposal-async-iteration with intent to implement for Chrome and other browsers. This is a proposal for adding async iterators to TypeScript.

This means adding the async iterator interface as well as async generators statements and the for - await loop.

(from the repo:)

An async iterator is much like an iterator, except that its next() method returns a promise for a { next, done } pair. As noted above, we must return a promise for the iterator result pair because both the next value and the "done" state of the iterator are potentially unknown at the time the iterator method returns.

cc @domenic @zenparsing

Usage

I have a presentation I gave on it here:
https://docs.google.com/presentation/d/1r2V1sLG8JSSk8txiLh4wfTkom-BoOsk52FgPBy8o3RM/edit?usp=sharing where I build autocomplete using async iterators.

(from the repo)

The async iteration statement: for-await-of

We introduce a variation of the for-of iteration statement which iterates over async iterable objects. An example usage would be:

for await (const line of readLines(filePath)) {
  console.log(line);
}

Async for-of statements are only allowed within async functions and async generator functions (see below for the latter).

During execution, an async iterator is created from the data source using the [Symbol.asyncIterator]() method.

Each time we access the next value in the sequence, we implicitly await the promise returned from the iterator method.

Async generator functions

Async generator functions are similar to generator functions, with the following differences:

For example:

async function* readLines(path) {
  let file = await fileOpen(path);

  try {
    while (!file.EOF) {
      yield await file.readLine();
    }
  } finally {
    await file.close();
  }
}

This function then returns an async generator object, which can be consumed with for-await-of as shown in the previous example.

Status

This feature already works in Babel and has progressed as far as other supported features such as object spread ({...obj}). Python, Dart and other language already support async iteration.

I think we should consider adding it to TypeScript.

christyharagan commented 7 years ago

I think this would be great. As a pattern Async Iterators are very useful, and something I use in my projects all the time.

The ReactiveX guys wrote a JS polyfill/proof-of-spec over at https://github.com/Reactive-Extensions/IxJS. I re-wrote this as pure TypeScript at https://github.com/christyharagan/IxJS. The library itself includes operators over Iterators+AsyncIterators, and it would be awesome to replace the "polyfill" component with an official TS implementation.

benjamingr commented 7 years ago

@christyharagan regenerator runtime has a working polyfill already. Now that async/await is out with the new compiler arch I think TS can transpile this sort of thing relatively easily.

mhegazy commented 7 years ago

Duplicate of https://github.com/Microsoft/TypeScript/issues/11326

Implemented by https://github.com/Microsoft/TypeScript/pull/12346

benjamingr commented 7 years ago

Awesome, thanks