Skip to content

Instantly share code, notes, and snippets.

@tuvshuud
Last active December 12, 2020 13:35
Show Gist options
  • Save tuvshuud/8516492 to your computer and use it in GitHub Desktop.
Save tuvshuud/8516492 to your computer and use it in GitHub Desktop.
NodeJS ийн тухай

Хоёр дахь NodeJS ийн тухай ярилцах сэдэв бол Event-driven asynchronous callbacks болон Event-loop.

Эхлээд өмнөхөөсөө үргэлжлүүлье. Сүүлд энгийн http server хийж үзсэн тэр жишээг үргэлжлүүлэн авч үзье.

var http = require("http");
http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);

Hello World http server ийм байсан бол өөрөөр бас ингэж бичиж болно болно.

var http = require('http');
var onRequest = function(request, response) { //дурын миний нэрлэсэн функц ийн нэр onRequest
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}
var server = http.createServer(onRequest);
server.listen(8888);

Сонирхолтой нь http модуль ийн createServer функц onRequest функц ийг параметр ээр авсан байгаа. Эхний жишээ нь дээр бас л мөн функц дамжуулсан. Тэгэхдээ нэргүй функц /Anonymous function/. Функц ээр функц дамжуулж болдог юм бол үүнийг тайлбарлахдаа дараах жишээнд авч үзье.

function say( word ){ //word гэх argument ийг аваад console дээр хэвлэх үүрэгтэй функц
	console.log(word);
}
function do( someFunction, value ){    
	someFunction(value);
}

Эхний parameter нь функц, дараах нь нэг утга. Тэгээд эхний parameter ээр ямар функц орж ирнэ тэр функц руу хоёр дахь parameter ийн утгыг дамжуулж байна.

do(say, "Hello World");//say гэх функц руу Hello World гэсэн утгыг дамжуул гэсэн үг
do(say, "Mongolia");

Тэгвэл одоо say гэдэг функ ны оронд дурын нэг функц дуудаж үзье. Яадаг вэ гэхээр оруулсан string ийг урвуугаар нь хэвлэдэг функц.

do(function(str){
	console.log(str.reverse());
}, "Mongolian NodeJS Developers");

Энэний гаралт нь ойлгомжтой биздээ тэ? Эдгээр жишээнүүдийг тест хийх бол дурын js файл нээгээд бичээд node өөр ажиллуулаад үзээрэй. Иймэрхүү загвараар math ийн үндсэн 4 үйлдэл хийх функц бичээд үзээрэй. Жишээ нь do(add, 4, 5); do(hasah, 3, 1); гэж дуудагдаад хэвлэх функц.

Функцын callback гэж нэр томъёо байгаа. Дээрхийг ойлгосон бол дараах жишээ нь дээр callback ийг үзүүлье.

function add( a, b, callback ){ 
	var c = a + b;
	callback(c);	
}

//add гэх функц ийн эхний хоёр param нь 2 тоо, тэгээд нийлбэрийг нь олоод callback функц руу дамжуулна. //callback нь дурын нэр бөгөөд add функцыг дуудахдаа ямар функ дуудна тэр байх болно. За одоо add функц //дуудаж үзье.

add(4, 5, function(value){
	console.log(value);	
});

add(1, 1, function(value){
	console.log(value);	
});

Гэх мэтээр дуудна. Callback param д тэр нэргүй үл танигдах функц ийг дамжуулсныг харж байгаа байх. Одоо энэ функц ээр нэлээн олон хос тоонуудын нийлбэрийг тус тусд нь олж үзье. Дандаа ямар anonymous функц дамжуулах биш нэг хэвлэдэг функц бичээд add функц ийн callback болгож өгье.

var printMe = function(value){
	console.log(value);
}

add(20, 30, printMe);
add(30, 40, printMe);
add(50, 60, printMe);

Нэг иймэрхүү.

---За яг үндсэн гарчигийн тухайд Яагаад ийм загвараар програм аа бичих вэ гэхээр NodeJS ийн талаар нэг дурьдаагүй нь NodeJS ийн бидний бичсэн код ийг хэрхэн execute хийж байгаа байдал. NodeJS бол Evented Server side javascript. Монголоор одоо юу гэх юмбдээ. Execute хийхдээ NodeJS нэг loop дотор руу явж ороод аль түрүүлж process хийгдсэнийг нь execute хйигээд яваад байна гэсэн үг. Монголоор яг event loop ийг тийм гэсэн үг гээд хэлж бас чадахгүй байгаа юм би. Мэддэг нь нээрээ яг ийм юм байна гэтэл нь тайлбарлаад өгөөрөй :). Тэгэхдээ дараах дурьдах жишээ нүүдээр тулгуурлаад өөр өөрсдийнхөөрөө ойлгоод аваарай. Мэддэг нэг нь шууд алгасаад яваарай.

Event loop ийг захиа хүргэж өгдөг post man гэж бодъё. Түүний хувьд захиа болгон event гэсэн үг. Захиа бүрийг хүргэж өгөх гэж манай хүн тухайн захианы хаяг руу явах замаар явна. Тэр зам бол тухайн event / хүргэж өгөх үйлдэл / -д хувиарлагдсан callback функц болно. Манай хүн хөөрхий нэг хос 2 хөлтөй болохоор нэг удаад нэг л захиа хүргэж өгөх замаар л явж чадна. Гэтэл нэг захиаг хүргэж өгөх гээд явж байтал нэг хүн шинэ захиа өгөөд хүргээд өгөөч гээд өгөхөөр нь авна. Энэ тохиодолд манай хүн шинэ захиаг хүргэж өгөхөөр явна. /Учир нь хүн бүр шуудангын газар өгөөд байхад тэр хүн яаралтай болоод хүргэж өгдөг хүнд шууд өгсөн байх :)/. Шинэ захиаг хүргэж өгсөний дараа буцаад өөрт байгаа захиануудыг хүргэж өгөхөөр үргэлжлүүлэн явна.

За одоо бараг NodeJS яагаад сая сая хандалтыг богино хугацаанд хариулах чадвартай байгааг гадарлаж байгаа байх.

var http = require("http");
http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello\n");
  setTimeout(function(){
  	response.end("World\n");
  }, 2000);
  response.end();
}).listen(8888);

Энэ http server яах вэ гэхээр энэхүү сервер лүү curl багажаар хандалт өгөөд үзвэл Hello гэж бичээд 2 секундын дараа World гэж бичнэ. Тэнд setTimeout() async функц байгааг харж байгаа байх. setTimeout() нь эхний argument нь callback, дараа нь хэдэн секундын дараа callback функц дотор байгаа код ыг execute хийх вэ гэх секундын тоог millisecond аар өгөх тоо юм. curl http://localhost:8888/ //ab ApacheBench гээд багаж аар benchmark хийх бол ab -r -n 100 -c 1000 http://127.0.0.1:8888/

Хэрвээ 2 хандалт нэгэн зэрэг өгөх бол хоёуланг нь ижил 2 секундын дараа World гэж бичнэ. 100 хандалт байсан ч 2 секунд. Тэхдээ яг нарийн ярих юм бол ~2,0053 сек. Харин php apache server яаж хариулах байсан бол? 4 хандалт зэрэг өгөхөд эхнийх 2 сек, дараагийнх хандатад 4 секундын дараа хариулна. Дараагынхд нь 6, 8 сек удаж байж хариулна.

NodeJS нэгэн зэрэг өгсөн хандалтад бараг ижил хугацаанд хариулж байна вэ гэхээр response.write('Hello') гэж execute хийсний дараа 2 сек хүлээх учир cpu idle буюу хийх зүйлгүй болно. Тиймээс дараагын хандалтыг хүлээж аваад дараагын хандалтын 2 сек ийг хүлээж байх зуур эхний хандалтын 2 сек болохоор response.end('World'); ийг execute хийнэ.

Харин apache server тухайн php дэх кодыг бүрэн дуусахыг хүлээсээр нэгэн зэрэг өгөгдсөн дараагын хандалтууд удаашраад үлдэнэ гэсэн үг. Хэрвээ 2 секундын timeout ын оронд баазаас асар их мэдээлэл түүх process байсан бол яах бол??

Дараах холбоосоор орж benchmark тест үзээрэй http://zgadzaj.com/benchmarking-nodejs-basic-performance-tests-against-apache-php

Сүүлд нь хэлэхэд application ээ asynchronous загварт оруулж бичихгүй бол NodeJS дээр хийсний хэрэг юу билээ.

Дараагынхаар хэрхэн хандалтыг чиглүүлэх буюу routing, GET, POST дата боловсруулах, application ээ хэрхэн module уудад хуваах талаар бичье гэж бодож байна.

Part 3

@pagvaa
Copy link

pagvaa commented Oct 9, 2017

hi. ene hesgiig tailbarlaad uguuch bayrlalaa,
response.writeHead(200, {"Content-Type": "text/plain"});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment