Help us understand the problem. What is going on with this article?

Promise再入門② ~async/await編~

More than 3 years have passed since last update.

概要

前回の続きです。
今回はPromiseを同期処理っぽく書ける「async/await」編です。

async/awaitの背景

ES6で実装されたPromiseの誕生により、
非同期処理がすごく簡単に書ける様になりました。

ただ、書き方はどうしても特殊で、
普段のプログラムでは見ない形です。
(モダンJSに慣れている人なら違和感はないと思いますが。)

そこで、Promiseをよりシンプルに且つ可読性が高まる様にとラッピングされたのが、
async/await 」の記法です。

何か特別な新しい考え方という訳ではなくて、
あくまでも、非同期をより読みやすくする新文法ぐらいの認識で問題ないと思います。

async/awaitはES7(ES2016)で実装されています。

async/awaitの使い方

async

asyncは関数宣言の前に記載します。
asyncが記載された関数は、必ずPromiseを返す様になります。

const func = async () => {
  return 23;
};

上のコードをasyncなしで書くと以下になります。

const func = () => {
  return new Promise((resolve) => {
    resolve(23);
  });
};

await

awaitはasync関数内でのみ使える文法です。
awaitはPromise.then(result => result))のラッパーで、
thenチェーンを使わずに、同期処理の様な記述で非同期処理を記載できます。
それにより可読性がグンと上がります。
(トップレベルでのawaitの使用は不可能)

const func = async () => {
  return 23;
};

const awaitFunc = async () => {
  // resolveが23のPromiseオブジェクトが出力される
  console.log(func());
  // func().then(result => result)で23が出力される
  console.log(await func());
};

awaitFunc();

awaitで同期っぽく書いている例が以下になります。
(awaitの付与でPromiseの完了を待っている状態)

const sleep = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(23);
    }, 3000);
  });
};

const awaitFunc = async () => {
  await sleep();
  // awaitでPromise終了を待ってから、logが出力される。
  console.log('done!!!');
};

awaitFunc();

awaitはPromiseの結果を返すので、以下の様な書き方もできます。

const sleep = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(23);
    }, 3000);
  });
};

const awaitFunc = async () => {
  const result = await sleep();
  // 23が出力される。
  console.log(result);
};

awaitFunc();

ちなみに、awaitを使わずに書いた場合こうなります。

const sleep = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(23);
    }, 3000);
  });
};

const awaitFunc = async () => {
  sleep()
    .then((result) => {
      console.log(result);
    });
};

awaitFunc();

これだけではいまいち良さはわかりませんが、
コールバック地獄や、Promiseのthen地獄、Promise.allでの並列処理などをたくさん書いている人は、
恩恵がイメージ出来るのではないかと思います。

終わり

async/awaitを使う事で、同期処理っぽく非同期処理が書けるイメージができたかと思います。

前回の冒頭で書いた通りで、
モダンJSでは非同期の取り扱いが非常に重要です。

async/awaitでしっかり可読性をあげれば、
「あれ?undfinedになってる...」のあるあるパターンともおさらばかと思います。

ES7での実装ですが、今後のスタンダードな書き方になると思うので、
積極的に利用していこうと思います。

tfrcm
React / ReactNative / Go / TypeScript / AWS / Docker / k8s
https://gemcook.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした