GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Async Iteration and down-level Generators by rbuckton · Pull Request #12346 · microsoft/TypeScript

Conversation

@rbuckton

@rbuckton Ron Buckton (rbuckton) commented Nov 18, 2016 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

This PR adds full support for Async Generators and Async Iteration (for..await..of) as per the current TC39 Proposal for all script targets. It also contains full support for Generators in ES5/3, including for..of, spread, and iterator destructuring.

Iterators

ES6 introduced Iterator, which is an object that exposes three methods, next, return, and throw, as per the following interface:

interface Iterator<T> {
  next(value?: any): IteratorResult<T>;
  return?(value?: any): IteratorResult<T>;
  throw?(e?: any): IteratorResult<T>;
}

This kind of iterator is useful for iterating over synchronously available values, such as the elements of an Array or the keys of a Map. An object that supports iteration is said to be "iterable" if it has a Symbol.iterator method that returns an Iterator object.

Async Iterators

The Async Iteration proposal introduces an AsyncIterator, which is similar to Iterator. The difference lies in the fact that the next, return, and throw methods of an AsyncIterator return a Promise for the iteration result, rather than the result itself. This allows the caller to enlist in an asynchronous notification for the time at which the AsyncIterator has advanced to the point of yielding a value. An AsyncIterator has the following shape:

interface AsyncIterator<T> {
  next(value?: any): Promise<IteratorResult<T>>;
  return?(value?: any): Promise<IteratorResult<T>>;
  throw?(e?: any): Promise<IteratorResult<T>>;
}

An object that supports async iteration is said to be "iterable" if it has a Symbol.asyncIterator method that returns an AsyncIterator object.

Generators

ES6 also introduced "Generators", which are functions that can be used to yield partial computation results via the Iterator interface and the yield keyword. Generators can also internally delegate calls to another iterable through yield *. For example:

function* f() {
  yield 1;
  yield* [2, 3];
}

Async Generators

The Async Iteration proposal introduces "Async Generators", which are async functions that also can be used to yield partial computation results. Async Generators can also delegate calls via yield* to either an iterable or async iterable:

async function* f(p) {
  yield 1;
  await p;
  yield* [2, 3];
  yield* (async function *() { 
    await p; 
    yield 4; 
  })();
}

As with Generators, Async Generators can only be function declarations, function expressions, or methods of classes or object literals. Arrow functions cannot be Async Generators. Async Generators require a valid, global Promise implementation (either native or an ES6-compatible polyfill), in addition to a valid Symbol.asyncIterator reference (either a native symbol or a shim).

The for-await-of Statement

Finally, ES6 introduced the for..of statement as a means of iterating over an iterable. Similarly, the Async Iteration proposal introduces the for..await..of statement to iterate over an async iterable:

async function* g() { ... }
async function f() {
  for await (const x of g()) {
  }
}

The for..await..of statement is only legal within an Async Function or Async Generator.

Generators and Iteration for ES5/3

In addition, the following changes are included to bring full support for Generators to ES5/ES3:

  • Added a -downlevelIteration compiler option, used when targeting ES5 or ES3.
    • When set, the compiler uses new type check and emit behavior that attempts to call a [Symbol.iterator]() method on the iterated object if it is found, and creates a synthetic array iterator over the object if it is not. This requires a native Symbol.iterator or Symbol.iterator shim at runtime for any non-array values.
    • When not set, array destructuring, spread, and for..of are only supported for arrays as is the current behavior in TypeScript 2.1 and earlier.
  • Array Destructuring now uses Symbol.iterator in ES5/3 if available when using -downlevelIteration, but can be used on an Array even if it does not define Symbol.iterator at run time or design time.
  • Spread elements in Array, Call, and New expressions use Symbol.iterator in ES5/3 if available when using -downlevelIteration, but can be used on Array even if it does not define Symbol.iterator at run time or design time.
  • for..of statements support Symbol.iterator in ES5/3 if available when using -downlevelIteration, but can be used on an Array even if it does not define Symbol.iterator at run time or design time.
  • Async Functions do not require a Symbol.iterator polyfill at run time to operate.

Related issues

  • Fixes Generator with Array Spread #11970 - Generator with Array Spread
  • Fixes Asynchronous Iterations #11326 - Asynchronous Iterations
  • Fixes for-of with map.keys() gives TS2495 #11209 - for-of with map.keys() gives TS2495
  • Fixes iterators with ES5 target #4031 - iterators with ES5 target
  • Fixes ES6 Generator support #1564 - ES6 Generator support

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

normalser, alitaheri, TobiaszCudnik, yortus, glen-84, jonaskello, jwbay, piotrwitek, gulshan, drywolf, and 54 more reacted with thumbs up emoji jwbay, piotrwitek, drywolf, AdamWillden, msemikin, HerringtonDarkholme, pleerock, glen-84, aluanhaddad, mischkl, and 31 more reacted with hooray emoji piotrwitek, AdamWillden, msemikin, HerringtonDarkholme, pleerock, alfaproject, aluanhaddad, mischkl, Mischi, thenameisflic, and 16 more reacted with heart emoji
All reactions
  • 👍 64 reactions
  • 🎉 41 reactions
  • ❤️ 26 reactions
Ron Buckton (rbuckton) added 21 commits October 24, 2016 16:21
@rbuckton
Move emit helpers into related transformers
6453fde
@rbuckton
Clean up and consolidate destructuring transform
86091d7
@rbuckton
Emit for full down-level generators
a2e0b19
@rbuckton
Merge branch 'master' into asyncGenerators
fea6827
@rbuckton
Relaxed ES2015 restrictions for generator type check
cb85356
@rbuckton
Type checking for async iterables and async generators.
c6ee25d
@rbuckton
Merge branch 'emitHelper' into asyncGenerators
74ec093
@rbuckton
type checking for pseudoiterable
bd86778
@rbuckton
Updated baselines
549ac8f
@rbuckton
Merge branch 'asyncGeneratorsUpLevel' into asyncGenerators
b5cc96c
@rbuckton
Added emit transforms for async generators.
4b5686a
@rbuckton
Parse, check, and downlevel emit for for-await-of
4f3fb80
@rbuckton
Added emit helper checks for async generators
a4036c7
@rbuckton
Merge branch 'emitHelper' into asyncGenerators
ab1dc52
@rbuckton
Merge branch 'improveImportHelpersDiagnostics' into asyncGenerators
d6a5e39
@rbuckton
Add for-await-of, always use Symbol for iterables.
28d23ce
@rbuckton
Updated baselines
df303c9
@rbuckton
Added conformance tests for async generators
e53263e
@rbuckton
Conformance tests for for-await-of
42085a6
@rbuckton
ES6 tests for async generators
c758359
@rbuckton
ES5 tests for async generators
281c890
@msftclas Microsoft Contribution License Agreements (msftclas) added the cla-not-required label Nov 18, 2016
@normalser normalser mentioned this pull request Nov 18, 2016
ES6 Generator support #1564
Closed
Ron Buckton (rbuckton) added 7 commits November 18, 2016 10:32
@rbuckton
Update es2017 library and baseline
1af8ac8
@rbuckton
Merge branch 'master' into asyncGenerators
1c0917a
@rbuckton
Fix lint warnings
2f6ac58
@rbuckton
Added iterationMode switch, consolidate some tests, cleanup
c72509b
@rbuckton
Revert diagnostic error number change
32bcc97
@rbuckton
Tests for iterationMode=iterable
38b7757
@rbuckton
Merge branch 'master' into asyncGenerators
1980334
@mhegazy Mohamed Hegazy (mhegazy) modified the milestones: TypeScript 2.2, TypeScript 2.3 Feb 6, 2017
@Wykks Guillaume de Jabrun (Wykks) mentioned this pull request Feb 7, 2017
Convert codebase to Typescript alex3165/react-mapbox-gl#114
Merged
@TonyPythoneer

TonyYang (TonyPythoneer) commented Feb 10, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

This PR is planed on TypeScript 2.3 release. 😭
I hope this can be released soon.

benjamingr, thetechnick, rikkit, and frederickfogerty reacted with thumbs up emoji jhwegener reacted with confused emoji
All reactions
  • 👍 4 reactions
  • 😕 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Ron Buckton (rbuckton) added 2 commits February 10, 2017 09:46
@rbuckton
Merge branch 'master' into asyncGenerators
3e427f4
@rbuckton
Merge branch 'master' into asyncGenerators
dedf4a7
@rbuckton

Ron Buckton (rbuckton) commented Feb 15, 2017

Copy link
Copy Markdown
Contributor Author

Mohamed Hegazy (@mhegazy), Is there anyone else you want to review this or should I merge?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

mhegazy
Mohamed Hegazy (mhegazy) reviewed Feb 15, 2017
View reviewed changes
Comment thread Jakefile.js
});

var esnextLibrarySource = [
"esnext.asynciterable.d.ts"

@mhegazy Mohamed Hegazy (mhegazy) Feb 15, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to update VS setup to include this file as well.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
mhegazy
Mohamed Hegazy (mhegazy) reviewed Feb 17, 2017
View reviewed changes
Comment thread src/compiler/comments.ts Outdated
function forEachLeadingCommentToEmit(pos: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) {
// Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
if (containerPos === -1 || pos !== containerPos) {
if ((containerPos === -1 || pos !== containerPos)) {

@mhegazy Mohamed Hegazy (mhegazy) Feb 15, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the parens are not needed

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/comments.ts Outdated
function forEachTrailingCommentToEmit(end: number, cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) => void) {
// Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
if (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd)) {
if ((containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd))) {

@mhegazy Mohamed Hegazy (mhegazy) Feb 15, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts
@@ -21132,7 +21287,7 @@ namespace ts {
function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
const sourceFile = getSourceFileOfNode(location);
if (isEffectiveExternalModule(sourceFile, compilerOptions)) {
if (!isDeclarationFile(sourceFile) && isEffectiveExternalModule(sourceFile, compilerOptions)) {

@mhegazy Mohamed Hegazy (mhegazy) Feb 16, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need this here, should not the new helpers only be visible in expressions?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mhegazy Mohamed Hegazy (mhegazy) Feb 16, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it is needed, then it should be isInAmbientContext

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Ron Buckton (rbuckton) added 3 commits February 16, 2017 17:16
@rbuckton
PR feedback
344a9d2
@rbuckton
Merge branch 'master' into asyncGenerators
cf72ceb
@rbuckton
Minor fixes after merging from master
11f58ea
@rbuckton
Ron Buckton (rbuckton) merged commit 03b9066 into master Feb 17, 2017
@rbuckton
Ron Buckton (rbuckton) deleted the asyncGenerators branch February 17, 2017 01:41
@mhegazy Mohamed Hegazy (mhegazy) mentioned this pull request Feb 17, 2017
iterators with ES5 target #4031
Closed
@chrisprice Chris Price (chrisprice) mentioned this pull request Mar 23, 2017
Add support for findAll honesty-store/cruft#1
Closed
@mhegazy Mohamed Hegazy (mhegazy) mentioned this pull request Mar 28, 2017
emit generators when targeting es5 #14903
Closed
This was referenced Apr 20, 2017
Allow NodeList in for-of loop ES5 mode #4947
Closed
Can't iterate over (U)Int8Array, (U)Int16Array, (U)Int32Array, etc. using for ... of #10005
Closed
for..of with iterators #3164
Closed
Loop with for ... of over a Map #14185
Closed
for-of does not work with DOM collections when target is ES3 or ES5 #2696
Closed
@jocull

James O'Cull (jocull) commented May 30, 2017

Copy link
Copy Markdown

Just curious, why is the downlevelIteration still undocumented under tsc --help? It seems to work, but there's no mention of it, and the errors leading up to needing it are unhelpful.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mhegazy

Mohamed Hegazy (mhegazy) commented May 30, 2017

Copy link
Copy Markdown
Contributor

Just curious, why is the downlevelIteration still undocumented under tsc --help?

it is, just use tsc --help --all

jocull, SlurpTheo, and olingern reacted with thumbs up emoji
All reactions
  • 👍 3 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@BurtHarris Burt Harris (BurtHarris) mentioned this pull request Jun 30, 2017
Please provide ES5 target tunnelvisionlabs/antlr4ts#311
Open
@2Pacalypse- Marko Žarković (2Pacalypse-) mentioned this pull request Jul 21, 2017
Es6 taget ShieldBattery/node-interval-tree#4
Closed
@marclaval Marc Laval (marclaval) mentioned this pull request Jan 11, 2018
fix(benchpress): should still support selenium_webdriver < 3.6.0 angular/angular#21477
Closed
@microsoft Microsoft (microsoft) locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@sandersn Nathan Shively-Sanders (sandersn) sandersn approved these changes
@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) Awaiting requested review from DanielRosenwasser
@ahejlsberg Anders Hejlsberg (ahejlsberg) Awaiting requested review from ahejlsberg
@vladima Vladimir Matveev (vladima) Awaiting requested review from vladima
+1 more reviewer
@mhegazy Mohamed Hegazy (mhegazy) mhegazy left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

TypeScript 2.3

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

12 participants

@rbuckton @mischkl @screendriver @glen-84 @benjamingr @dead-claudia @sandersn @klihelp @TonyPythoneer @jocull @mhegazy @msftclas
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.