Generator and async Methods

Methods can be generators (*name(), Generators), async (Promises and Asynchrony) or both. A generator named [Symbol.iterator] makes instances iterable. A subclass without a constructor gets constructor(...args) { super(...args); } automatically.

Generator, async and async generator methods (an ES module)JavaScriptLive
class Playlist {
  constructor(...songs) { this.songs = songs; }
  *[Symbol.iterator]() { yield* this.songs; }                  // generator method: iterable
  async *stream() { for (const s of this) yield await s; }     // async generator method
  async first() { return (await this.stream().next()).value; } // async method
}
class Mix extends Playlist {}          // implicit constructor(...args) { super(...args); }
const mix = new Mix('Intro', 'Outro'), streamed = [];
for await (const song of mix.stream()) streamed.push(song);
console.log(streamed, [...mix], await mix.first());