Node.js

特徴:イベント駆動、非同期処理、単一スレッド・プロセス

★インストール

nodebrew: nodeのバージョンを管理・切替するツール

Ubuntu の場合

sudo apt-get update

sudo apt-get install nodejs npm

Mac の場合

brew install node

CentOS の場合

yum install gcc gcc-c++

yum install nodejs npm –enablerepo=epel

★アップデート

npm update -g npm

すべてのパッケージ

npm update -g

Node.jsのアップデートツール

npm install -g n

Stableの確認

n --stable

Latestの確認

n --latest

指定バージョンにアップデート

n 8.9.4

★npmについて

https://docs.npmjs.com/getting-started/what-is-npm

npm config set registry http://registry.npmjs.org/

npm install -g yo

npm install -g grunt-cli

npm install -g bower

npm install mysql --save

ls /usr/local/lib/node_modules/

--save package.json の dependencies に追記

--save-dev package.json の devDependencies に追記

--save-optional package.json の optionalDependencies に追記

★Windowsにproxy設定

call npm -g config set proxy http://<IP>:<PORT>

call npm -g config set https-proxy http://<IP>:<PORT>

call npm config list

npm -g config delete proxy

npm -g config list

★同期 vs 非同期

サンプル1

>同期

var filenames = fs.readdirSync(".");

for (i = 0; i < filenames.length; i++) {

console.log(filenames[i]);

}

console.log( process.getuid() ); ←blocking

>非同期

fs.readdir(".", function(err, filenames){

var i;

for (i = 0; i < filenames.length; i++) {

console.log(filenames[i]);

}

});

console.log( process.getuid() ); ←non-blocking

サンプル2

>同期

var filenames = fs.readdirSync(".");

for (i = 0; i < filenames.length; i ++) {

stats = fs.statSync("./" + filenames[i]);

totalBytes += stats.size;

}

console.log(totalBytes);

>非同期

var count = filenames.length;

for (i = 0; i < filenames.length; i++) {

fs.stat("./" + filenames[i], function(err, stats){ ←並列処理

totalBytes += stats.size;

count--;

if (count === 0) {

console.log(totalBytes); ←関数内に実行が必要

}

});

}

★コード再利用(遂次実行の場合)

方法1

var prevFinFlg = true;

var intervalId = setInterval(TargetFunc, 1000);

function TargetFunc(){

if(prevFinFlg == false) {

return;

}

prevFinFlg = false;

hostRequest = http.request(requestOptions, function(response){

response.on('data', function(chunk){

responseHTML = responseHTML + chunk;

});

response.on('end', function(){

console.log(responseHTML);

...

if(canStop){

clearInterval(intervalId);

return;

}

prevFinFlg = true;

});

});

hostRequest.end();

}

方法2(推奨)

TargetFunc();

function TargetFunc(){

hostRequest = http.request(requestOptions, function(response){

response.on('data', function(chunk){

responseHTML = responseHTML + chunk;

});

response.on('end', function(){

console.log(responseHTML);

...

if(canStop){

return;

}

TargetFunc(); ←非同期処理なので、再帰ではない

});

});

hostRequest.end();

}

★Event Loop

// macrotask queue

setTimeout(()=>{

console.log('timer1')

// microtask queue

Promise.resolve().then(function() {

console.log('promise1')

})

}, 0)

// macrotask queue

setTimeout(()=>{

console.log('timer2')

// microtask queue

Promise.resolve().then(function() {

console.log('promise2')

})

}, 0)

ブラウザの場合: timer1 => promise1 => timer2 => promise2

Nodeの場合: timer1 => timer2 => promise1 => promise2