JavaScript
TypeScript
ECMAScript

setTimeoutをasync/awaitプログラミングで使う

More than 1 year has passed since last update.

setTimeoutのようなコールバック型の非同期関数をasync/await化する、言い換えるとPromiseを返すようにするのは、以下のような関数を用意してあげることでできます。

function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

こうしておくと、

async function my_function() {
  ...
  await timeout(5000);
  ...
~
}

のようにasync/awaitコンテキストで、もしくはPromiseチェーンの起点としてこのラッパ関数を使えます。
こんな短い記述なのでわざわざ関数にラップするまでもなく直書きでも十分ですが。

async function my_function() {
  ...
  await new Promise(resolve => setTimeout(resolve, 5000));
  ...
~
}

TypeScriptなら上記timeoutの定義はこうなりますね。

function timeout(ms: number): Promise<void> {
  return new Promise<void>(resolve => setTimeout(resolve, ms));
}

また、失敗時のコールバックも登録できる関数、例えば$.ajaxとかなら

function jq_ajax(url, options) {
  return new Promise((resolve, reject) =>
    $.ajax(url, options).done(resolve).fail(reject));
}

のようにreject(Promiseのコンストラクタに渡すコールバックの2個目の引数)を使うことでラップできます。この失敗ケースはPromisecatch()で拾うかasyncコンテキストのtry-catchで捕まえるかできるわけです。