JavaScriptでasync/awaitの備忘録

JavaScriptの復習

JavaScriptはシングルスレッドで動いています。 つまり、call stack(コードを読み込み、実行するもの)が一つしかないので、処理を一つずつ実行していくようになっています。

非同期処理の必要性

順番に処理が実行されていく中で、仮に時間のかかる処理が一つ間にあった場合、Javascriptがその処理をしている間に他のものは実行されません。

そこで重たい処理をJavascript以外に任せられたらJavaScriptは処理をすすめることができますよね?

それを可能にしたのが非同期処理ということです。

非同期処理の例

非同期処理が行えるオブジェクトとしてPromise developer.mozilla.org

があります。async/awaitを理解するためにはPromiseを理解しないといけないです。Promiseが返ってくるfetch()を使った例を紹介します。 fetch()はHTTPリクエストの発行とレスポンスを取得する関数です。

JSONPlaceholder - Fake online REST API for testing and prototyping

というサイトを使ってAPIを叩いて見ます。ブラウザの検証を開き、consoleで試しにfetch()を実行してみます。

fetch('https://jsonplaceholder.typicode.com/todos/1')

するとPromiseが帰ってきているのがわかります。

続いて、

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json))

を実行してみると、JSONのデータが帰って来ていることが確認できます。

これがPromiseを使った書き方です

async/awaitについて

async functionは呼び出されるとPromiseを返します。 awaitはPromiseの結果が帰って来るまで待機しておく演算子のことです。 awaitはasync function内でないと利用できないです。

async/awaitの例

先程の例をasync/awaitを使って同様の処理を書いてみると

const fetchTodos = async function(){
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
    const data = await response.json()
    console.log(data)
}
fetchTodos()

先程と同様の結果が帰ってきます。

このようにPromiseで連結された処理を多用するよりもasync/awaitを使って読みやすく書くことができます。

そんな変わらないじゃん。むしろ、Promiseほうがわかりやすいと思った方もいるかもしれません。

もう少し複雑な例を使って見ましょう。

Promise chainの場合

const routes = [
    'todos',
    'posts',
    'users'
]
const baseUrl = 'https://jsonplaceholder.typicode.com/'

Promise.all(routes.map(route => 
    fetch(baseUrl+route + '/1').then(res => res.json())
)).then(array => {
    console.log('todos', array[0])
    console.log('posts', array[1])
    console.log('users', array[2])
}).catch("Error")

async / awaitを使った場合

const fetchData = async function(){
    try {
        const [todos, posts, users] = await Promise.all(routes.map(route => 
            fetch(baseUrl+route + '/1').then(res => res.json())
        )) 

        console.log('todos', todos)
        console.log('posts', posts)
        console.log('users', users)
    } catch(e) {
        console.log('Error, ', e)
    }
}

JSの復習として、非同期処理の説明やasync/awaitの書き方について紹介しました。

どこか間違った部分があれば、教えていただければ幸いです。