10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TypeScript: asyncとジェネレータ両方使う方法

10
Last updated at Posted at 2020-06-23

この投稿では、以下の2つを説明します。

  • TypeScriptでasyncとジェネレータの両方を使った関数を定義する方法
  • その関数をforで呼び出す方法

asyncとジェネレータの両方を使った関数を定義する

asyncとジェネレータを使った関数は、asyncキーワードをジェネレータ関数function*に冠することで定義できます:

async function* getNumbers() {
  await sleep(1000)
  yield 1

  await sleep(1000)
  yield 2

  await sleep(1000)
  yield 3
}

戻り値の型注釈を与える場合は、AsyncGenerator<T>を使います:

async function* getNumbers(): AsyncGenerator<number>

以上で、asyncなジェネレータが定義できます。最終形態はこんなかんじになります:

async function* getNumbers(): AsyncGenerator<number> {
  await sleep(1000)
  yield 1

  await sleep(1000)
  yield 2

  await sleep(1000)
  yield 3
}

function sleep(milliseconds: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, milliseconds))
}

asyncなジェネレータ関数を呼び出す方法

asyncなジェネレータ関数を呼び出すには、for awaitを使います。

async function main() {
  for await (const number of getNumbers()) {
    console.log(number)
  }
}

トラブルシューティング

Cannot find name 'AsyncGenerator'.

コンパイル時にAsyncGenerator型が見つからないというエラーが出る場合は、コンパイル設定を変更する必要があります。

AsyncGeneratorはES2018で導入されたので、libもしくはtargetを変更します。

生成されるJavaScriptコードがES2018のシンタックスでいい場合は、target"ES2018"以上にするだけで解決します:

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2018"
  }
}

生成するJavaScriptコードをES2018未満にする必要がある場合は、lib"es2018.asyncgenerator"を設定することでコンパイルが通るようになります:

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2017",
    "lib": ["es2017", "es2018.asyncgenerator"]
  }
}
10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?