163
157

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.

async, await入門

Last updated at Posted at 2019-03-12
1 / 15

はじめに

この記事は、社内勉強会の発表用として作成したものを、一部加工して公開しているものです。
間違っていることもあると思いますが、コメントで指摘していただけると幸いです。


Promiseのおさらい

  • 非同期関数を扱うためのインターフェース
new Promise((resolve, reject) => {
    //非同期処理
    hoge.readFile(file, function(err, data){
      if (err) {
        reject(err); // errがあればrejectを呼び出す
        return;
      }

      resolve(data); // errがなければ成功とみなしresolveを呼び出す
    });
});
  • resolveは成功時に呼ぶ関数
  • rejectは失敗時に呼ぶ関数

Promiseってどういう風に使うの?

axios.get("https://hoge.fuga.com")
    .then(response => console.log(response.status)) //成功時の処理
    .catch(error => console.log(error.response.status))  //失敗時の処理

Promiseがつらいときってどんな時?

例えば…

非同期関数の結果を次の非同期関数で使いたいとき
thenのネストが増えていって辛い

asyncFunction1()  
    .then(value1 => {  
        return asyncFunction2(value1)  
            .then(value2 => {  
            return asyncFunction3(value1, value2)
                .then(value3 => {
                console.log(value3)
            })
        })  
    });

async,awaitとは

そういったPromiseの辛いところを簡潔に書ける(全てが全て書けるわけではない。)

また、雑に言うとasync,awaitはPromiseの処理のシンタックスシュガーなので、Promiseでできないことはできない。


asyncとは

非同期関数を定義する関数宣言のこと。
function や アロー関数に async を付けると「async 関数」を定義できます。

async 関数ってなにするの?

呼び出されるとPromiseを返す
returnした場合その値がresolveされたものとされる。
throwした場合その値がrejectされたものとされる。

あまり意味はないが、asyncだけ使用してawaitは使用しなくても大丈夫。


awaitとは

async関数内でPromiseの結果(resolve、reject)が返されるまで待機する(処理を一時停止する)演算子のこと。

async function sample() {
    //値が返ってくるまで待機
    const result = await samplePromise();

    console.log(result);
}

//Promiseで書くと…
function sample2(){
    return samplePromise()
        .then(result => {
        console.log(result);
    })
}

async,awaitの使用例

まずは簡単なものから

const hoge = () => Promise.resolve(1)
const fuga = () => Promise.resolve(2)

const main = () => {
    hoge().then(x => {
        fuga().then(y => {
            console.log(x + y)
        })
    })
}
main()

const hoge = async () => 1
const fuga = async () => 2

const main = async () => {
    const x = await hoge()
    const y = await fuga()
    console.log(x + y)
}
main()

並列の非同期処理

Promise版

const hoge = value => {
  return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 2);
        }, 1000);
    })
}

const fuga = value => {
  return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 3);
        }, 500);
    })
}

const promiseAllSample = () => {
    const promise1 = hoge(5);
    const promise2 = hoge(10);
    const promise3 = promise2.then(value => {
        return fuga(value);
    });

    return Promise.all([promise1, promise2, promise3]);
}

promiseAllSample().then(([a, b, c]) => {
    console.log(a, b, c); // => 10 20 60
});

async,await版

const hoge = value => {
  return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 2);
        }, 1000);
    })
}

const fuga = value => {
  return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 3);
        }, 500);
    })
}

const promiseAllSample = async () => {
    const [a, b] = await Promise.all([hoge(5), hoge(10)]);
    const c = await fuga(b);

    return [a, b, c];
}

promiseAllSample().then(([a, b, c]) => {
    console.log(a, b, c); // => 10 20 60
});

Array.map()の利用も出来る。

const hoge = value => {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 2);
        }, 1000);
    })
}

const promiseMapsample = async () => {
    const values =[5, 10, 15];
    return await Promise.all(
        values.map(async value => await hoge(value))
    );
}

promiseMapsample().then(([a, b, c]) => {
    console.log(a, b, c); // => 10 20 30
});

エラーハンドリング

async,awaitはPromiseのシンタックスシュガーなので、catchをそのまま使える。

const errorHandling= async () => {
    const result = await sample()
    console.log(result) // エラー時は到達しない
}

errorHandling()
    .catch(console.log)

おまけ

  • axiosとかでよく使う書き方。いちいちresponse.dataと書くのがめんどくさいときに
const { data } = await axios.get("https://hoge.fuga.com")
  • awaitにしないほうが綺麗なとき。
const x1 = await func()
const x2 = await filter1(x1)
const x3 = await filter2(x2)

// ↓ ↓ ↓

const x = await func().then(filter1).then(filter2)

参考

Promise - JavaScript | MDN
Promiseを使う - JavaScript | MDN
async function - JavaScript | MDN
await - JavaScript | MDN
Promise と async/await の理解度をもう1段階上げる - Qiita
async/await 入門(JavaScript) - Qiita
async関数においてtry/catchではなくawait/catchパターンを活用する - Qiita

163
157
5

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
163
157

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?