m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

javascriptのPromiseとasync / awaitについて少し試す

Promiseは

並列処理でちょっと前に学習したやつで

function sampleTask1() {
    return new Promise(function(resolve, reject) {
        setTimeout(function () {
            console.log('sample1');
            resolve("sample1");
        }, 3000);
    });
}

って定義したら

sampleTask1()
    .then(function(result) {
        console.log("result", result);
    })
    .catch(function(error) {
        console.log("error");
    });

で実行した際に非同期で動作して、正常時にはresolve、異常時にはrejectで返却するやつです。

今回は?

async / awaitがある
これは
非同期処理をもう少しスッキリ書けるらしい

まずは今までのやつ

console.log("start");
Promise.resolve()
    .then(function() {
        return new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log("sample2-1");
                resolve("sample2-1");
            }, 16);
        });
    })
    .then(function(result) {
        console.log("result", result);
    })
    .then(function() {
        return new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log("sample2-2");
                resolve("sample2-2");
            }, 10);
        })
    })
    .then(function(result) {
        console.log("result", result);
    })
    .then(function() {
        return new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log("sample2-3");
                resolve("sample2-3");
            }, 5);
        });
    })
    .then(function(result) {
        console.log("result", result);
    });
console.log("end");

これが

// まず、Promiseを返す関数を定義
function taskA() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log("sample2-1");
            resolve("sample2-1");
        }, 16);
    })
}
function taskB() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log("sample2-2");
            resolve("sample2-2");
        }, 25);
    })
}
function taskC() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log("sample2-3");
            resolve("sample2-3");
        }, 5);
    })
}

// 逐次処理を行うやつ
async function taskSample1() {
    // 1つずつ実行
    const res1 = await taskA();
    console.log("res1:", res1);
    const res2 = await taskB();
    console.log("res2:", res2);
    const res3 = await taskC();
    console.log("res3;", res3);

    // 配列に設定して順次実行
    const taskList = [
        taskA, taskB, taskC
    ];
    for (let i=0;i<taskList.length;i++) {
        const res = await taskList[i]();
        console.log(`res${i}=`, res);
    }
}

// 実行
console.log("start");
taskSample1();
console.log("end");

こうなる
「async」を定義した関数はPromiseを返すようになるらしい、
また「await」は処理結果を返すまで待機してくれるとのこと
基本的には両方セットで使うみたい。

fetchを使う場合は

async function getRequest() {
    const response = await fetch("http://127.0.0.1:8080/sample_api1", {
        method: "POST", // *GET, POST, PUT, DELETE, etc.
        mode: "cors", // no-cors, cors, *same-origin
        cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
        credentials: "same-origin", // include, same-origin, *omit
        headers: {
            "Content-Type": "application/json; charset=utf-8"
        },
        redirect: "follow", // manual, *follow, error
        referrer: "no-referrer", // no-referrer, *client
        //body: JSON.stringify("{}"), // 本文のデータ型は "Content-Type" ヘッダーと一致する必要があります
    });

    const data = await response.json();
    console.log(data);
}

console.log("start");
for (let i=0;i<5;i++) {
    getRequest();
}
console.log("end");

うん、なんとなく同期処理っぽくかけるのが良い感じですね(^o^)
今回は記載しませんがPromise.allで複数の並列処理後の結果を取得してごにょごにょとかいうのもやってみよう

所感

結構スッキリかけるようになったようになっています。
ただ、Promiseの仕組みを十分に理解することやエラーの箇所の記載がないようにエラーに関する挙動をどうするかを今後検討していきたい。