Javascript async&await

  • 2021年8月20日
  • 2021年8月20日
  • Kwon

前回はjavascriptのpromiseを利用して非同期処理する方法についてお話しました。

例)
データ取得にて10秒掛かる場合、10秒後、コンソールにて結果が出力されます。
もし下部にUI関連処理がある場合、その10秒間、白い画面のままで表示されます。

function getUser() {
    // 例えばデータ取得処理に10秒かかる

    return 'ok';
}

const user = getUser();
console.log(user);

上記のものをpromiseを利用して下記のようになります。

function getUser() {
    return new Promise((resolve, reject) => {
    // 例えばデータ取得処理に10秒かかる
    resolve('ok');
    });
}

const user = getUser();
console.log(user);

上記のようにpromiseを使うと、下部にUI関連処理があってもその処理は処理通りに進んで、リクエストしたデータが取得したらその結果がconsole.logへ表示されます。

今日はjavascriptのasync&awaitを利用してもっと簡単に非同期処理をする方法についてお話します。
例えば上記でpromiseで書いた内容をasyncで書き換えすると

async function getUser() {
    // 例えばデータ取得処理に10秒かかる

    return 'ok';
}

const user = getUser();
user.then(console.log);

簡単でしょう。
単純に関数の前にasyncを付けるだけです。
asyncが付いた関数はpromiseを返します。
なので、thenを使ってconsole.logへ書き込みするようにします。

簡単なサンプルコートを使って、awaitについてお話します。

◆ サンプルコード

// 時間パラメーターを持って、呼出するとその時間分待って結果を返す。
function getUser(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// 5秒の時間でAクラスのユーザーを取得
async function getAclass() {
    await getUser(5000);    // getUser(5000)からデータを取得するまで待ちます
    return 'A class member !!';
}

// 5秒の時間でBクラスのユーザーを取得
async function getBclass() {
    await getUser(5000);
    return 'B class member !!';
}

// 全ユーザーを取得
function getAllUser() {
    return getAclass().then(aClass => {
        return getBclass().then(bClass => `${aClass} + ${bClass}`)
    });
}

getAllUser().then(console.log);

サンプルコードを実行すると10秒後、下記の結果が出力されます。
サンプル結果

上記のようにasync関数の中にawaitが入ります。
await getUser(5000)``getUser(5000)から結果が変えてくるまで待ちます。

async function getAclass() {
    await getUser(5000);
    return 'A class member !!';
}
// 上記のものをPromiseに書き換えすると下記のようになるんでしょう。
function getAclass() {
    return delay(5000)
    .then(()=>'A class member !!');
}

上記ではpromiseの.then`を一回しか使ってないですが、何回も重ねて使った場合、`async`&`awaitを使った方が読みやすいと思います。

下記のところがサンプルコードで、わざと「.then」を使ったサンプルコードの一部です。

// 全ユーザーを取得
function getAllUser() {
    return getAclass().then(aClass => {
        return getBclass().then(bClass => `${aClass} + ${bClass}`)
    });
}

// 上記のコードをasync&awaitを使って書き換えすると下記のようになります。

async function getAllUser() {
    const aClass = await getAclass();
    const bClass = await getBclass();
    return `${aClass} + ${bClass}`;
}

上記のコードを実行すると10秒後、下記のようにサンプルコードと同じ結果が出力されます。
サンプル結果

ここで一つ、Aクラスのユーザーの呼出で5秒、Bクラスのユーザーの呼出で5秒が掛かって、10秒後、出力されています。
今回、Aクラスのユーザーの呼出とBクラスのユーザーの呼出には関係ないので、順序に持ってくる必要が内での平行に行うようにしましょ。

async function getAllUser() {
    const aClassPromise = getAclass();
    const bClassPromise = getBclass();
    const aClass = await aClassPromise;
    const bClass = await bClassPromise;
    return `${aClass} + ${bClass}`;
}

上記のようにするとAクラスのユーザーを取得するまで待ったなく、Bクラスのユーザーを取得します。
実行すると今回は5防後、下記のようにサンプルコードと同じ結果が出力されます。
サンプル結果

サンプルコードを整理すると下記のようになります。

// 時間パラメーターを持って、呼出するとその時間分待って結果を返す。
function getUser(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// 5秒の時間でAクラスのユーザーを取得
async function getAclass() {
    await getUser(5000);    // getUser(5000)からデータを取得するまで待ちます
    return 'A class member !!';
}

// 5秒の時間でBクラスのユーザーを取得
async function getBclass() {
    await getUser(5000);
    return 'B class member !!';
}

// 全ユーザーを取得
async function getAllUser() {
    const aClassPromise = getAclass();
    const bClassPromise = getBclass();
    const aClass = await aClassPromise;
    const bClass = await bClassPromise;
    return `${aClass} + ${bClass}`;
}

getAllUser().then(console.log);
最新情報をチェックしよう!

Kwonの最新記事8件