NodeJs(四)----Node.js非同期処理の各種表記

22280 ワード

異歩とは何か
  • 同期とは、プログラム(プロセス/スレッド)が一つのタスクの処理中に、他のタスクを挿入しないことであり、IO等のCPUを占有しない操作にあっても、その終了を待って処理を継続することである.
  • いわゆる非同期とは、プログラム(プロセス/スレッド)がタスクの処理中に、IO動作に遭遇した場合、プログラム(プロセス/スレッド)の制御権を他のタスクに解放し、IO操作の結果が戻ったら次の処理を継続する他のタスクを挿入します.
  • 簡単に言えば、同期はコントロールを解放しません.非同期はコントロールを解放します.
    非同期的な書き方
    コールバック関数
    まず3つのtxtファイルを作成しました.(one.txt、two.txt、three.txt)
    コードは以下の通りです
    const fs = require('fs');
    
    fs.readFile('one.txt', 'utf8', function (err, data) {
        if (err) throw err;
        console.log(data);
        fs.readFile('two.txt', 'utf8', function (err, data) {
            if (err) throw err;
            console.log(data);
            fs.readFile('three.txt', 'utf8', function (err, data) {
                if (err) throw err;
                console.log(data);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
            });
        });
    });
    console.log("finish");
    //       finish,     fs.readFile()      ,             ,                   。
    
  • 1、関数fs.readFile()は、非同期的にファイルのすべてのコンテンツを読み取るために使用され、関数自体が戻り値を持っていない.読み込んだファイルの内容は非同期に戻り、コールバック関数で処理されます.
  • 、関数fs.readFile()の第二のパラメータはオプションパラメータであり、符号化方式が指定された場合、対応する符号化方式の文字列を返す.指定されていない場合は、ファイルのバイナリコンテンツに戻り、対応するタイプはバッファerであり、buf.toString()方法により対応する文字列に変換することができる.
  • 3、コールバック関数の最初のパラメータはエラーオブジェクトでなければなりません.エラーがなければエラーオブジェクトの値はnullです.
  • シリアルとパラレル
    通常、同期、非同期、シリアル、パラレルの違いはよく分かりませんが、同期はシリアルであり、非同期はパラレルであると言われています.
    これらのコードを改造すると、並行して実行されるようになります.
    const fs = require('fs');
    fs.readFile('one.txt', 'utf8', function (err, data) {
        if (err) throw err;
        console.log(data);
    });
    fs.readFile('two.txt', 'utf8', function (err, data) {
        if (err) throw err;
        console.log(data);
    });
    fs.readFile('three.txt', 'utf8', function (err, data) {
        if (err) throw err;
        console.log(data);
    });
    console.log("finish");
    
    //結果からもわかるように、3つのファイルは並行して読み込まれているので、どれが先に読み終わったらランダムで、コード書きの順番には関係ありません./順番に書いたコードは順番に実行されます.これは典型的な同期プログラミングの考え方です.
    Promiseオブジェクト
    Promiseオブジェクトは、非同期動作の状態と結果を表すことができ、提供された.then()方法を用いて複数の非同期動作を「直列」にすることができ、then()方法自体もPromiseオブジェクトに戻る.
    同じように3つのファイルを順番に読み込むタスクの例は以下の通りです.
    var readFilePromise = require('fs-readfile-promise');
    readFilePromise('two.txt', 'utf8')
        .then(function(data) {
            console.log(data);
        })
        .then(function() {
            return readFilePromise('one.txt', 'utf8');
        })
        .then(function(data) {
            console.log(data);
        })
        .then(function() {
            return readFilePromise('three.txt', 'utf8');
        })
        .then(function(data) {
            console.log(data);
        })
        .catch(function(err) {
            console.log(err);
        });
    console.log("finish");
    
  • Promiseの3つの状態
  • Promiseオブジェクトは、非同期動作を表し、pending(進行中)、fulfilled(成功した)、rejected(失敗した)の3つの状態がある.
    Promiseの状態の変化については、一つはpendingがfulfilledになり、一つはpendingがrejectになる場合のみです.
  • Promiseはどう使いますか?promiseの基本的な使い方
    ES 6はPromiseオブジェクトがPromiseのインスタンスを生成するためのコンストラクタであると規定しています.
    実例の対象はここで、まずnewの全く新しいPromiseの例です.
    const promise = new Promise(function(resolve, reject) {
        // ... some code
        if(/*       */) {
            resolve(value);
        } else {
            reject(error);                    
        }
    });
    
    Promiseコンストラクタは匿名関数をパラメータとして受け入れ,関数ではresoveとrejectの二つのパラメータをそれぞれ受け入れていることがわかる.この2つのパラメータは内蔵の2つの関数を表しています.
  • レシオの役割は、Promiseオブジェクトの状態を「未完了」から「成功」に変化させ、非同期動作が成功したときに呼び出し、非同期動作の結果をパラメータとして伝達することである.
  • rejectの役割は、Promiseオブジェクトの状態を「未完了」から「失敗」に変化させ、通常は非同期動作に失敗したときに呼び出し、非同期動作の結果をパラメータとして渡すことである.
  • 受信状態のコールバック
    Promiseのインスタンスが生成された後、then法を用いてreolved状態とreject状態を指定することができる.
    //  “    ”   
    promise.then(function(value) {
        //success
    },function(error) {
        //failure
    });
    
    可視,then法はパラメータとして2つのコールバック関数を受け入れることができる.最初のコールバック関数はPromiseオブジェクトの状態がreolvedになったときに呼び出します.第二のコールバック関数はプロミセオブジェクトの状態がrejectiedになったときに呼び出します.このうち、2番目の関数は任意です.必ずしも提供しなくてもいいです.また、この2つの関数は、パラメータとしてPromiseオブジェクトから流れる値を受けます.
    簡単な例を以下に示した.
    function timeout(ms) {
        return new Promise(function(resolve, reject) {
            setTimeout(resolve, ms, 'done');                 
        });
    }
    timeout(3000).then(function(value) {
        console.log(value); //done
    });
    
    上記の例は、3 s後に、新規作成されたPromiseオブジェクトをpending状態からresoloved状態に変化させ、続いてthen方法のバインディングをトリガするコールバック関数である.
    また、Promiseは新築時にすぐ実行しますので、直接Promiseの状態を変えることもできます.
    //  “    ”  1
    let promise = new Promise(function(resolve, reject) {
        console.log('Promise');
        resolve();
    });
    
    promise.then(function() {
        console.log('resolved.');
    });
    
    console.log('Hi!');
    // Promise
    // Hi!
    // resolved
    
    上のコードはPromiseの例を新規作成してすぐ実行しますので、まず出力するのは「Promise」です.resoveに続いて、thenのコールバック関数をトリガします.これは現在のスクリプトの全同期タスクが完了した後に実行されます.だから、次に出力するのは「Hi!」です.最後に「resoved」です.