コールバック <- Node流並行処理 <- TetraCalibers
TetraCalibers :
    -   for : science student & programmer
Node流並行処理 - 1
コールバック
    Node.jsをなんとか理解しようと噛み砕いた思考の跡。

     

    イベントループによる並行処理

     

    誰かが投稿を書いている間は何も操作できない…そんな世にも恐ろしいSNSを生まないために、Webアプリケーションでは並行処理が必要不可欠になる。

     

    例えば、あなたは会社に新卒で入社したばかりで、上司の指示の通りに仕事をこなすしかないとしよう。

     

    このとき、上司に「書類を50部印刷しておいて」とだけ言われたとしたら、印刷が完了した後に次の指示を仰ぐことになる。

     

    ブロッキング
    プログラムの進行をそこで一時停止させてしまうような時間のかかる処理
    同期処理
    完了するまで次に進まないような処理

     

    一方、「書類を50部印刷して、注文データを表にまとめておいて」と言われたとしたら、書類を印刷している間に表作成を進めることができる。

     

    つまり、『次に何をすべきなのか』がわかっていれば、待ち時間を有効活用することができる。

     

    イベントループによる並行処理
    完了後のタスクを指定してそれを実行し、アプリケーション自体の処理は先に進めてしまう
    ノンブロッキング
    時間のかかる処理でありながら、プログラムの進行を止めないような処理
    非同期処理
    完了を待機せずに次に進んでしまうような処理

     

    コールバック

     

    (定義なので当たり前だが)非同期処理では、処理の完了が前後することがある。

     

    setTimeout(
        () => console.log('1秒経ってから実行されます'),
        1000
    )
    console.log('先に実行されます')
    

     

    コールバックの中で発生したエラーは、try...catchではハンドリングできない。 そのため、コールバックパターンで実装されたAPIは、コールバックの第1引数としてエラーを渡すようになっていることが多い。

     

    var fs = require('fs')
    
    fs.readdir(
        '.',
        (err, files) => {
            console.log('エラー:', err);
            console.log('カレントディレクトリのファイル:', files)
        }
    )
    

     

    コールバックパターンは、順序を指定した処理には向かない。

     

    例えば、掲示板の新規投稿ボタンが押された時の次のような処理を考えてみる。
    新着投稿が確実に画面に反映されてから、Twitterで投稿通知をツイートしたいのだ。
    1. Ajaxでサーバに投稿データを送る
    2. AjaxでサーバからDB更新完了ステータスを受け取って、新規投稿を画面に表示
    3. Ajaxでサーバに表示完了ステータスを送って、サーバ側でTwitterに新規投稿通知をツイート

     

    コールバックには完了時の処理を記述するから、コールバックの中に次のAjax処理を書くことになり、次のようなネスト地獄に陥る。(以下は擬似的なコード)
    postAjax(data, (err, result1) => {
        if (err) { console.log('通信失敗') }
        displayAjax(result1, (err, result2) => {
            if (err) { console.log('更新失敗') }
            tweetAjax(result2, (err, result3) => {
                if (err) { console.log('ツイート失敗') }
            })
        })
    })
    

     

    コールバックヘル
    コールバックの中にコールバックを記述することで、ネストが深くなり読みづらくなる現象