トッカンソフトウェア

Promise

今回はPromiseをやります。


Promise

JavaScriptは通常であれば上から順に実行されます。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">

        function func1() {
            msg += "→1"
        }

        function func2() {
            alert(msg);
        }

        var msg = "0";

        func1();
        func2();

    </script>
</head>

<body>
</body>

</html>
結果

0→1


Ajaxの実行やsetTimeoutを使った処理など非同期処理がある場合、処理が行われる順番が前後することがあります

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">

        function func1() {

            // 100ミリ秒後に実行
            setTimeout(() => {
                msg += "→1"
            }, 100);
        }

        function func2() {
            alert(msg);
        }

        var msg = "0";

        func1();
        func2();

    </script>
</head>

<body>
</body>

</html>
結果

0


この非同期の処理に対して意図した順番で処理を行いたい場合、Promiseを使います。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">

        function func1(funcX) {

            // 100ミリ秒後に実行
            setTimeout(() => {
                msg += "→1";
                funcX();
            }, 100);
        }

        function func2() {
            alert(msg);
        }

        var msg = "0";

        // func1が終わったらfunc2を実行
        new Promise(func1).then(func2);

    </script>
</head>

<body>
</body>

</html>
結果

0→1


引数を指定


<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">

        function func1(funcX) {
            setTimeout(() => {
                funcX("Hello World");
            }, 100);
        }

        function func2(arg) {
            alert(arg);
        }

        // func1が終わったらfunc2を実行
        new Promise(func1).then(func2)

    </script>
</head>

<body>
</body>

</html>
結果

Hello World


Promiseを連続


<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">

        function func1(funcX) {
            setTimeout(() => {
                funcX("→1");
            }, 100);
        }

        function func2(arg) {
            return new Promise((funcX) => {
                setTimeout(() => {
                    funcX(arg + "→2");
                }, 100);
            });
        }

        // func1が終わったらfunc2を実行し、メッセージ表示
        new Promise(func1).then(func2).then(arg => {
            alert(arg);
        });

    </script>
</head>

<body>
</body>

</html>
結果

→1→2


並列処理


<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">


        const pro1 = new Promise((funcX) => {

            setTimeout(() => {

                funcX("b");

            }, 100);
        });

        const pro2 = new Promise((funcX) => {

            funcX("a");
        });

        // 全部が終わったら
        Promise.all([pro1, pro2]).then((arg) => {
            alert("all:" + arg);
        });
        // 1つでも終わったら
        Promise.race([pro1, pro2]).then((arg) => {
            alert("race:" + arg);
        });

    </script>
</head>

<body>
</body>

</html>
結果

race:b
all:b,a


async、await


<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">

        function func1(arg) {
            return new Promise((funcX) => {
                setTimeout(() => {
                    funcX(arg + "→2");
                }, 100);
            });
        }

        // awaitを使う場合、functionにasyncを付ける
        async function func2() {

            // Promiseが終わるまで待つ
            let msg = await func1("→1");
            alert(msg);
        }

        func2();
        // asyncはPromiseを戻すため、以下の実行も可能
        // func2().then(() => {
        //     alert("end");
        // });

    </script>
</head>

<body>
</body>

</html>
結果

→1→2

上記サンプルをPromise、thenで書き換えると以下になります。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <script type="text/javascript">

        function func1(arg) {
            return new Promise((funcX) => {
                setTimeout(() => {
                    funcX(arg + "→2");
                }, 100);
            });
        }

        function func2() {

            let pro = func1("→1");

            // Promiseが終わるまで待つ
            pro.then((msg) => {
                alert(msg);
            });
        }

        func2();

    </script>
</head>

<body>
</body>

</html>


ページのトップへ戻る