• ..

git

    非同期 async-await

    async-awaitは、「いつ完了するか分からない処理」だけど「順番に実行したい」な事をするために使います。「コールバック地獄」と呼ばれていたような読みづらいコードをシンプルに書けます。

    構文

    functionの前、アロー関数なら(の前にasyncと書きます。

    async function foo() {
      /* ... */
    }
    const bar = async () => {
      /* ... */
    };

    そして、中でPromiseを返す関数の実行前にawaitと書けば、処理が終わるまでその場で待ってくれます。

    /**
     * 1病待つ
     * (`async`と書くと`Promise`だなとわかるのでオススメしたい)
     */
    const delay = async () => new Promise(r => setTimeout(r, 1000));
    
    (async () => {
      console.log('すぐ表示');
      await delay();
      console.log('1秒後表示');
      await delay();
      console.log('さらに1秒後');
    })();

    エラー処理

    await文の例外はtry-catchで扱えるようになります。

    class OversleepError extends Error {
      constructor() {
        super('寝坊した');
        Error.captureStackTrace(this, OversleepError);
      }
    }
    
    /**
     * 寝る
     */
    const sleep = async () => {
      /* ... */
      throw new OversleepError();
      /* ... */
    };
    
    (async () => {
      try {
        await sleep();
      } catch (err) {
        console.log(err instanceof OversleepError); // true
      }
    })();

    また、扱うのはPromiseなのでcatchで一旦受け取ってできるだけ処理するといったことも。

    /* 上の関数定義そのまま */
    
    const eatBreakfast = async () => {
      /* 食べる */
    };
    
    (async () => {
      const task = {
        breakfast: true
      };
    
      await sleep().catch(err => {
        if (err instanceof OversleepError) {
          task.breakfast = false;
          return;
        }
    
        // error が OversleepError じゃない場合、ここでは扱えないので
        // 再度 `catch` か `try-catch` で扱える形にして
        // 親スコープなどで処理する
        throw err;
      });
    
      if (task.breakfast) {
        await eatBreakfast();
      }
    })().catch(err => {
      /* OversleepError 以外のエラーを扱う */
    });