Node JS sẽ chạy code như nào khi nhận nhiều request một lúc?

var express = require('express')
var app = express()

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)

chào mọi người
mình đang gặp khó với 2 câu hỏi không biết search kiểu gì?

vấn đề đầu tiên , mình mới học code server, trước mình chỉ code giải các bài toán thì logic run code sẽ là chạy từ trên xuống dưới, trái qua phải , 1 chương trình khi đó sẽ có 3 phần: khởi đầu, thân chương trình và kết thúc, kể từ việc học coder server, cái khởi đầu- thân chương trình-kết thúc nó không rõ ràng cụ thể cái lệnh app.listen(), nó luôn trực chờ để hứng request, vậy khi có request tới thì đoạn code trên sẽ lại run từ đầu phải không ạ? hay nó sẽ run tính từ dòng /đoạn nào?

vấn đề thứ 2 là mình đang không hiểu là mình tạo 1 cái server để nó hứng request tới, nếu mà có 100 request tới cùng lúc, khi đó ứng với mỗi request thì đoạn code middlware ở trên sẽ lại run lại từ đầu trong mỗi process riêng hay 100 request này, sẽ chỉ do 1 main process phục vụ mà thôi?

Bạn nào có link trả lời vấn đề này gửi mình, mình đọc để được chi tiết nhé!

note: đoạn code trên của mình là đoạn code helloworld đơn giản, tuy nhiên câu hỏi của mình rộng và nó áp dụng cho tất cả code khác.
cảm ơn mọi người

1/ app.get() không phải là một đoạn code theo thứ tự, mà chỉ là thêm một request handler cho express server, prototype của nó sẽ như này get(path, handler).
Mỗi khi có request đến server thì express sẽ đưa request đó qua middleware, rồi middleware tiếp tục gọi đến request handler.

Và chương trình của bạn vẫn chạy đúng theo tuần tự của nó, bạn bối rối chỗ thứ tự của chương trình có lẽ là do anonymous function. Viết rõ ra nó sẽ như này:

function handler(req, res) {
  res.send('Hello World!')
}

app.get('/', handler);

Tức đoạn này nó chỉ thêm một handler type get vô app. còn việc gọi hàm handler được thực hiện sâu bên trong express, mỗi khi có request được gửi đến.

2/ câu trà lời là nó sẽ xử lý 100 cái request. . . cùng lúc. Để hiểu được sao lại vậy thì bạn sẽ phải tìm hiểu thêm một khái niệm đó là asynchronous, và đây cũng là mấu chốt cho cả 2 câu hỏi của bạn.

P/s: Bạn hãy tìm hiểu về async trên JS trước để biết nó là gì, rồi có thể đọc sâu hơn về asynchronous và tìm hiểu cách hoạt động của asynchronous.

8 Likes

mình đã học về async, lập trình async áp dụng cho các thao tác I/O, trong khi chờ 1 tác vụ I/O hoàn thành thì đoạn code phía sau được phép thực thi. Lập trình async khác lập trình đa luồng.
ở câu 2 mình hỏi, theo như Bạn vừa đề cập để thực thi 100 request bắt đầu cùng lúc ( parallel work), tức là 100 request này, được run trên cùng 1 thread?

V như bạn nói nếu phải tạo 100 threads thì nó khác đa luồng chỗ nào. :slight_smile:

5 Likes

mình đã sửa lại cmt trên cho rõ

Vậy không biết bạn có bỏ qua phần event loop khi học về async không nhỉ. . .

3 Likes

event loop mình học rồi Bạn.
câu 2 mình chỉ hỏi khi 100 request tới cùng lúc thì mỗi request sẽ được phục vụ riêng 1 process hay sẽ có 100 process được tạo? (theo như mình tự học thì node js hiện chỉ có thể forked process ra các child process chứ hiện giờ nó chưa tạo thread được).
Bạn lưu ý mình không hỏi 100 request này làm code block bắt đầu cùng lúc hay không, mình chỉ quan tâm 100 request này nó sẽ run trên 1 process hay 100 process mà thôi, còn nếu bắt đầu cùng lúc thì ở 1 process cũng có thể bắt đầu cùng lúc được.

Cái phần quan trọng nhất bạn lại bỏ nó đi. :smiley:

Còn để trả lời nhanh thì nó sẽ chỉ chạy trên một process.

4 Likes

Cái phần quan trọng nhất bạn lại bỏ nó đi” bạn có thể nói cho tớ phần đó là để tớ học dc ko ?

setTimeout(() => console.log('before'), 0)

for (int i = 0; i < 1000000; i++) console.log(i); // 1 triệu lệnh này chắc chạy cũng vài giây

setTimeout(() => console.log('after'), 0)

trước khi thảo luận về vấn đề này, thì bạn có thể cho mình biết đoạn code trên trả về kết quả gì không?

5 Likes

Mình nói r đó. . .

3 Likes

nó sẽ in ra các số:
0,1,2,3,4,…1000
before
after

vì sao là settimeout 0s nhưng lệnh đầu tiên nó lại không chạy đầu tiên, hoặc nó không chen vô giữa cái đám i?

4 Likes
setTimeout(() => console.log('before'), 0)

for (int i = 0; i < 1000000; i++) {
    if (i === 500000) setTimeout(() => console.log('middle'), 0)
    else console.log(i)
}

setTimeout(() => console.log('after'), 0)

để câu hỏi trông thú vị hơn, mình xin sửa một tí
bạn có thể giải thích kết quả không?

6 Likes

output là
1234…499999 5010000…10000000

before
middle
after

do gặp tác vụ I/O thì nó cho task vào queue, còn task khác vẫn chạy bình thường

“100 request bắt đầu cùng lúc được” mình nghĩ rằng ko đúng, vì nó chỉ 1 thread chạy- làm sao có thể start 100 request cùng lúc được? mình sẽ tìm hiểu thêm kiến trúc của nó để xem điều này có đúng ko.

bạn có thể giải thích rõ. ở đây cái này là tác vụ IO? cái này là task? và cho task vào queue nghĩa là gì, có ý nghĩa gì? task khác ở đây là gì?

cách bạn giải thích cũng mơ hồ y như kiến thức của bạn

5 Likes

Mình nói là xử lý cùng lúc mà. :smiley:
Còn khi 100 cái request cùng đến server thì nó vẫn sẽ phải accept() từng cái một chứ. :kissing:

5 Likes

đoạn này bạn nói hơi rối, mình hơi khó hiểu

cảm ơn mọi người đã trả lời câu hỏi của mình

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?