20200107のNode.jsに関する記事は2件です。

async/await完全に理解した(JavaScript)

きっかけ

最近Node.jsを触る機会があるが、言語を体系的に勉強してきたわけではないので、必要な機能から調べながら使っている。
あるとき一定時間待ってから次の処理を行うシーケンス的なことをしたいなと思って調べたところ、やりたいことは「非同期処理」と言われるようだ。次のようなサンプルコードが出てきた。

コールバックを使う方法
const t0 = Date.now(); // 開始時刻を取得
console.log('開始: ' + (Date.now() - t0)); // 経過時刻をあわせて出力
setTimeout(function() {
    console.log('1秒後に実行されるはず: '+ (Date.now() - t0)); // 経過時刻をあわせて出力
}, 1000);
出力
開始: 0
1秒後に実行される: 1004

あーそーゆーことね完全に理解した(画像は脳内補完願います)
よし、ちゃんと1秒後に実行された。
じゃあ処理を2段階にしてみよう。

コールバックを使う方法2
const t0 = Date.now();
console.log('開始: ' + (Date.now() - t0));
setTimeout(function() {
    console.log('1秒後に実行されるはず: '+ (Date.now() - t0));
    setTimeout(function() {
        console.log('2秒後に実行されるはず: '+ (Date.now() - t0));
    }, 1000);
}, 1000);
出力
開始: 0
1秒後に実行されるはず: 1003
2秒後に実行されるはず: 2004

あーそーゆーことね完全に理解した(画像は脳内補完願います)
じゃあ10個に増やしてみよう。

コールバックを使う方法4
const t0 = Date.now();
console.log('開始: ' + (Date.now() - t0));
setTimeout(function() {
    console.log('1秒後に実行されるはず: '+ (Date.now() - t0));
    setTimeout(function() {
        console.log('2秒後に実行されるはず: '+ (Date.now() - t0));
        setTimeout(function() {
            console.log('3秒後に実行されるはず: '+ (Date.now() - t0));
            setTimeout(function() {
                console.log('4秒後に実行されるはず: '+ (Date.now() - t0));
                setTimeout(function() {
                    console.log('5秒後に実行されるはず: '+ (Date.now() - t0));
                    setTimeout(function() {
                        console.log('6秒後に実行されるはず: '+ (Date.now() - t0));
                        setTimeout(function() {
                            console.log('7秒後に実行されるはず: '+ (Date.now() - t0));
                            setTimeout(function() {
                                console.log('8秒後に実行されるはず: '+ (Date.now() - t0));
                                setTimeout(function() {
                                    console.log('9秒後に実行されるはず: '+ (Date.now() - t0));
                                    setTimeout(function() {
                                        console.log('10秒後に実行されるはず: '+ (Date.now() - t0));
                                    }, 1000);
                                }, 1000);
                            }, 1000);
                        }, 1000);
                    }, 1000);
                }, 1000);
            }, 1000);
        }, 1000);
    }, 1000);
}, 1000);

いやよく見たらクソむかつく(画像は脳内補完願います)

なんだこのネストの嵐は。
調べてみると、これはJavaScript界隈で言われているコールバック地獄というやつらしい。
更に調べてみると、イマドキのJavaScriptにはコールバック地獄を解消する方法が用意されているということがわかった。ですよねー。

Promise と async/await

コールバック地獄を解消する方法は2種類ほどあるらしい。
1. Promiseを使う方法
2. async/awaitを使う方法
後者のasync/awaitの方が新しくてイマドキらしい。ということで前者のPromiseは飛ばしても大丈夫かな。
というわけで、async/awaitの概要を調べてみた。

引用:async/awaitを使ったモダンな非同期処理 - Qiita

リピートミー。「async/awaitはPromiseで作られている」。

!!??

async関数はPromiseを返します。
この関数を呼び出すときにawaitを付けると、このコードはPromiseがresolvedかrejectedを返すまで停止します。

async/awaitを完全に理解するには、結局Promiseを理解しないといけないらしい

async/awaitの完全理解

この辺をじっくり読んでいろいろコードを書いて試した。

コードと解説

先程の10回待つ処理をasync/awaitを使って書くとこうなる。

async/awaitを使ったコード
const t0 = Date.now();
console.log('開始: ' + (Date.now() - t0));
asyncCall();

function wait1sec() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve();
        }, 1000);
    });
}

async function asyncCall() {
    await wait1sec();
    console.log('1秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('2秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('3秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('4秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('5秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('6秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('7秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('8秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('9秒後に実行されるはず: '+ (Date.now() - t0));
    await wait1sec();
    console.log('10秒後に実行されるはず: '+ (Date.now() - t0));
}
出力
1秒後に実行されるはず: 1009
2秒後に実行されるはず: 2013
3秒後に実行されるはず: 3015
4秒後に実行されるはず: 4019
5秒後に実行されるはず: 5022
6秒後に実行されるはず: 6028
7秒後に実行されるはず: 7029
8秒後に実行されるはず: 8036
9秒後に実行されるはず: 9042
10秒後に実行されるはず: 10046

おまけ

async は「エイシンク」と読むらしい。「アシンク」だと思ってた。
await は「アウェイト」で良いらしい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

nodeを終了する方法(コマンド)4選

nodeを終了する方法4選

① .exit

.exit と打つことで終了出来ます。

[name]MacBook-Pro:[filename] [name]$ node
Welcome to Node.js v13.5.0.
Type ".help" for more information.
> .exit
[name]MacBook-Pro:[filename] [name]$ 

② Ctrl + d

Ctrlを押しながらDを入力することで終了出来ます。
こちらが一番簡単ですが、2回Ctrl + Dを入力してしまうとターミナル自身が終了してしまうので注意が必要です。

[name]MacBook-Pro:[filename] [name]$ node
Welcome to Node.js v13.5.0.
Type ".help" for more information.
>  (ここで Ctrl + dを入力)
[name]MacBook-Pro:[filename] [name]$ 

③ Ctrl + c を2回入力

[name]MacBook-Pro:[filename] [name]$ node
Welcome to Node.js v13.5.0.
Type ".help" for more information.
>  (ここで Ctrl + cを入力)
(To exit, press ^C again or ^D or type .exit)
>   (ここで Ctrl + cを入力)
[name]MacBook-Pro:[filename] [name]$ 

④ Ctrl + c の次に Ctrl + d

表示は、③と同じ表示になります。
②と同様に、二回Ctrl + dを入力してしまうとターミナル自身が終了してしまうので注意が必要です。

[name]MacBook-Pro:[filename] [name]$ node
Welcome to Node.js v13.5.0.
Type ".help" for more information.
>  (ここで Ctrl + cを入力)
(To exit, press ^C again or ^D or type .exit)
>  (ここで Ctrl + dを入力)
[name]MacBook-Pro:[filename] [name]$ 

最後に

ターミナル終了の可能性がない、①か②をおすすめします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む