Skip to content

Latest commit

 

History

History
120 lines (96 loc) · 5.48 KB

async-function.adoc

File metadata and controls

120 lines (96 loc) · 5.48 KB

Async Functionとは

Async Functionとは非同期処理を行う関数を定義する構文です。 Async Functionは通常の関数とは異なり、必ずPromiseインスタンスを返す関数を定義する構文です。

Async Functionは次のように関数の前にasyncをつけることで定義できます。 このdoAsync関数は常にPromiseインスタンスを返します。

async function doAsync() {
    return "値";
}
// doAsync関数はPromiseを返す
doAsync().then((value) => {
    console.log(value); // => "値"
});

Async Functionではreturnした値の代わりに、Promise.resolve(返り値)のように返り値をラップしたPromiseインスタンスを返します。 そのため、このAsync Functionは次のように書いた場合と同じ意味になります。

// 通常の関数でPromiseインスタンスを返している
function doAsync() {
    return Promise.resolve("値");
}
doAsync().then((value) => {
    console.log(value); // => "値"
});

またAsync Function内ではawait式というPromiseの非同期処理が完了するまで待つ構文が利用できます。 await式を使うことで非同期処理を同期処理のように扱えるため、Promiseチェーンで実現していた処理の流れを読みやすくかけます。

Async Functionとawait式の大まかな動きをイメージするために、まずはPromise APIで書いたものと比較してみます。

ここでは、XHRの現代的なバージョンである Fetch API を使います。Fetch APIは指定したURLのリソースを読み書きでき、デフォルトでES Promisesに対応しています。

次のサンプルコードでは、https://azu.github.io/promises-book/json/book.jsonというURLからJSONデータを取得して、titleプロパティを取り出すgetBookTitle関数を実装していきます。

取得するhttps://azu.github.io/promises-book/json/book.jsonは次のような内容になっています。

/json/book.json
link:../json/book.json[role=include]

まずは、Fetch APIを使ってfetchBookTitle関数で取得したタイトルをコンソールに出力してみます。

fetchメソッドはPromiseを返します。このPromiseインスタンスはリクエストのレスポンスを表すResponseオブジェクトでresolveされます。 Response#jsonメソッドもPromiseを返します。このPromiseインスタンスは取得したリソースをJSONとしてパースしたオブジェクトでresolveされます。

fetchBookTitle関数は、次のようにfetchメソッドで取得したJSONのtitleプロパティでresolveされるPromiseインスタンスを返します。

function fetchBookTitle() {
    // Fetch APIは指定URLのリソースを取得しPromiseを返す関数
    return fetch("https://azu.github.io/promises-book/json/book.json").then((res) => {
        return res.json(); // レスポンスをJSON形式としてパースする
    }).then((json) => {
        return json.title; // JSONからtitleプロパティを取り出す
    });
}

function main() {
    // `fetchBookTitle`関数は、取得したJSONの`title`プロパティでresolveされる
    fetchBookTitle().then((title) => {
        console.log(title); // => "JavaScript Promiseの本"
    });
}

main();

次は、同様の処理をAsync Functionとawait式で実装してみます。 ここではまだ挙動を理解しなくても問題ありませんが、 Promise APIを使っていた場合に比べて、thenメソッドやコールバック関数がなくなっていることが分かります。

// `async`をつけて`fetchBookTitle`関数をAsync Functionとして定義
async function fetchBookTitle() {
    // リクエストしてリソースを取得する
    const res = await fetch("https://azu.github.io/promises-book/json/book.json");
    // レスポンスをJSON形式としてパースする
    const json = await res.json();
    // JSONからtitleプロパティを取り出す
    return json.title;
}

// `async`をつけて`main`関数をAsync Functionとして定義
async function main() {
    // `await`式で`fetchBookTitle`の非同期処理が完了するまで待つ
    // `fetchBookTitle`がresolveした値が返り値になる
    const title = await fetchBookTitle();
    console.log(title); // => "JavaScript Promiseの本"
}

main();

Async FunctionではPromiseの状態が変化するまで待つawait式という機能を利用できます。 Promiseでは結果をthenメソッドのコールバック関数で取得していたのが、await式の右辺にあるPromiseのresolveされた値が左辺の変数へと代入されます。そのため、Async Functionとawait式を使うことで非同期処理をまるで同期処理のように書けます。

この章では、このAsync Functionとawait式について詳しく見ていきます。

重要なこととしてAsync FunctionはPromiseの上に作られた構文です。 そのためAsync Functionを理解するには、Promiseを理解する必要があることに注意してください。