Nodejs xin chào thế giới

Tài liệu này hướng tới mục tiêu giúp bạn làm quen với việc phát triển các ứng dụng sử dụng Node. js và hướng dẫn bạn tất cả những thứ bạn cần biết về Javascript "nâng cao", vượt qua các hướng dẫn "Hello World" mà bạn thường thấy

status

Bạn đang đọc phiên bản mới nhất của cuốn sách này, điều này có nghĩa là sự thay đổi chỉ được thực hiện để bắt kịp với các bản cập nhật or cũng như lỗi của các phiên bản Node. js mới hơn. Thay đổi gần đây nhất vào ngày 01 tháng 07 năm 2013

Mã nguồn các ví dụ trong cuốn sách này đã được kiểm tra và xác nhận hoạt động tốt với phiên bản Node. js 0. 10. 12

Trang web này cho phép bạn đọc miễn phí từ trang 1 đến trang 21 của cuốn sách. Phiên bản đầy đủ được cung cấp miễn phí dưới dạng Sách điện tử không có DRM (PDF, ePub và định dạng cho Kindle). Xem thêm thông tin ở cuối trang

Đối tượng độc giả

Tôi chắc chắn rằng cuốn sách này phù hợp với các độc giả có kiến ​​thức về lập trình tương đương với tôi, tức là. đã có kinh nghiệm với ít nhất một ngôn ngữ lập trình hướng đối tượng như Ruby, Python, PHP hay Java, một chút kinh nghiệm về Javascript và không biết gì về Node. js

Hướng tới các đối tượng là các thành viên lập trình đã có kinh nghiệm với ít nhất một ngôn ngữ lập trình khác đồng nghĩa với việc cuốn sách này sẽ không đề cập đến các khái niệm cơ bản trong lập trình như. data type, variable, cấu trúc điều khiển cấu trúc v. v. Để hiểu rõ hơn về cuốn sách này, bạn cần nắm bắt những khái niệm trên

Tuy nhiên, hàm và đối tượng trong JavaScript có đôi chút khác biệt so với các ngôn ngữ khác nên nó sẽ được giải thích chi tiết hơn

Constructor

Đọc xong cuốn sách này cũng đồng nghĩa với việc bạn đã xây dựng được một ứng dụng web hoàn chỉnh có khả năng cho phép người dùng truy cập qua các trang khác nhau và tải tệp lên

Tuy nhiên những gì được đề cập trong cuốn sách này không mang tính chất "thay đổi thế giới", nhưng chúng ta sẽ tiến xa hơn là chỉ dừng lại ở việc thực hiện các ví dụ bằng cách xây dựng một khung có các thành phần đã đạt được. . Bạn sẽ được nhìn thấy nó trong ít phút nữa

Chúng ta sẽ bắt đầu bằng việc so sánh các khác nhau trong quá trình phát triển của JavaScript trong Node. js and in the browser

Tiếp theo đó, chúng ta sẽ bắt tay vào thực hiện ví dụ "Hello World" truyền hệ thống, ứng dụng Node. js cơ bản nhất

Cuối cùng chúng ta sẽ thảo luận về một ứng dụng có tính thực tiễn mà chúng ta muốn xây dựng, phân tích kỹ lưỡng các thành phần cơ bản không thể thiếu của nó, và bắt tay lần lượt vào từng phần

Như đã đề cập, song song đó chúng ta sẽ nghiên cứu một số khái niệm nâng cao về JavaScript, học cách áp dụng chúng, và cùng nghiên cứu tại sao nó lại tốt hơn những khái niệm tương tự trong các ngôn ngữ lập trình khác nhau

Mã nguồn hoàn thiện của ứng dụng có thể tải về tại địa chỉ kho lưu trữ Github của NodeBeginnerBook

JavaScript và Node. js

JavaScript and You

Trước khi đề cập đến các vấn đề mang tính kỹ thuật, hãy dành một chút thời gian để nói về bản thân bạn và mối quan hệ của bạn với JavaScript. Sự hiện diện của chương trình này cho phép bạn có thể tự đánh giá khả năng hiểu/liên kết các nội dung tiếp theo

Nếu bạn giống tôi, hãy bắt đầu từ "lập trình" HTML, bằng cách viết các tài liệu HTML. Bạn đã biết đến một thứ rất hay có tên JavaScript, nhưng từ trước đến nay bạn mới chỉ sử dụng nó ở mức độ hết sức cơ bản là tăng cường sự tương tác với người dùng cho các trang web của bạn

Cái mà bạn thật sự muốn là "cái gì mang tính thực tế", bạn muốn biết làm thế nào để xây dựng những trang web lớn và phức tạp - bạn học một ngôn ngữ lập trình có giới hạn như PHP, Ruby, Java và . (Phần mã sinh ra mã HTML)

Tuy nhiên, bạn vẫn quan tâm đến JavaScript, bạn thấy chúng thông qua các bài giới thiệu về jQuery, Prototype, hay tương tự như thế, khiến JavaScript trở nên cao cấp và phức tạp hơn với bạn, không nhất thiết phải dừng lại ở cửa sổ. mở()

Kiểm tra cho cùng thì tất cả vẫn chỉ dừng lại ở frontend (thực thi trên trình duyệt), tuy nhiên bạn biết thêm "gia vị" cho trang web của bạn bằng cách sử dụng jQuery, nhưng lạc quan mà nói, bạn chỉ là

And Node. js ra đời. JavaScript chạy phía máy chủ, thật tuyệt phải không?

Bạn quyết định sớm muộn gì cũng phải tìm hiểu về cái JavaScript cũ, mới đó. Nhưng đừng nóng lên, hãy viết ứng dụng bằng cách sử dụng Nút. js chưa phải là tất cả, hiểu được tại sao nó lại được viết như vậy mới gọi là - hiểu/nắm JavaScript. Và lần này mới là thực tế

Các vấn đề ở đây là. JavaScript thực sự có ở cả hai, kể cả ba loại khác nhau (từ trình trợ giúp DHTML giữa những năm 90, đến các thư viện phía khách/máy khách như jQuery, và bây giờ là phía máy chủ), không dễ dàng gì để tìm kiếm tài liệu. . js tạm ổn khiến bạn không cảm thấy giống như đang sử dụng JavaScript mà thực tế là đang phát triển nó

Hướng giải quyết. bạn đã là một học viên có kinh nghiệm lập trình, bạn không muốn học một công nghệ/kỹ thuật mới chỉ bằng cách mổ xẻ lung tung hoặc sử dụng sai mục đích;

Tuy rằng luôn có các tài liệu tham khảo chính thức rất đầy đủ tồn tại. Nhưng chỉ tài liệu tham khảo không thôi thì chưa đủ. Cái bạn cần ở đây là sự hướng dẫn

Vì thế mục đích của tôi là cung cấp một "người hướng dẫn" cho bạn

vài lời nhắc nhở

Có rất nhiều lập trình viên JavaScript dày đặc kinh nghiệm bên ngoài kia, nhưng tôi không phải là một trong số họ

Tôi thực sự chỉ là người vừa được đề cập đến ở giai đoạn trước. Tôi biết hoặc một hai "tí" về phát triển ứng dụng web ở phía phụ trợ, JavaScript "thực thụ" vẫn còn là mới đối với tôi, cả Node. js cũng vậy. Tôi mới học được một vài khía cạnh nâng cao của JavaScript gần đây. Tôi không phải là "trưởng lão luyện"

Đó cũng là lý do vì sao đây không phải là cuốn sách để bạn biến "từ tân binh thành chuyên gia". Chính xác mà nói, nó giúp bạn "từ lính mới trở thành lính mới kỳ cựu" hơn

Nếu không nhầm thì tôi đã khao khát có được một cuốn sách như thế này khi tôi bắt đầu tìm hiểu về Node. js

JavaScript phía máy chủ

Những "hiện thân" đầu tiên của JavaScript tồn tại trên trình duyệt. Nhưng đây thực sự chỉ là ngữ cảnh của nó. Người ta chưa rõ những cái mà bạn có thể làm với JavaScript chứ không hề đề cập đến những cái mà bản thân nó có thể làm được. JavaScript is a language "hoàn thiện". bạn có thể sử dụng nó trong nhiều ngữ cảnh và đạt được kết quả tương tự như bất kỳ ngôn ngữ nào đã "hoàn thiện" khác

And Node. js thực tế chỉ là một ngữ cảnh khác. nó cho phép bạn chạy mã JavaScript ở phía phụ trợ, vượt qua phạm vi trình duyệt

Để chạy được JavaScript phía phụ trợ, mã nguồn cần phải được biên dịch và. chạy. This main is task that Node. js chắc chắn, bằng cách sử dụng lại máy ảo V8 của Google, hay còn được biết đến là môi trường chạy JavaScript trên trình duyệt Google Chrome

Add into that, Node. js còn cung cấp rất nhiều thư viện bổ sung (mô-đun) hữu ích, vì thế bạn sẽ không phải viết ứng dụng của mình từ con số 0, ví dụ đơn giản nhất như hiển thị một dòng chữ nào đó ra màn hình

Vì vậy có thể nói Node. js bao gồm 2 trong 1. một môi trường chạy (runtime environment) và một thư viện

Để có thể tận dụng hết các tính năng này, bạn cần phải cài đặt Node. js. Thay vì lặp lại các bước hướng dẫn cài đặt ở đây, vui lòng làm theo hướng dẫn cài đặt công thức chính tại đây. Sau đó quay trở lại khi đã hoàn tất

"Chào thế giới"

Ok, hãy cùng bắt tay vào viết ứng dụng sử dụng Node. js first of them ta. "Chào thế giới"

Vui lòng mở chương trình biên tập (trình chỉnh sửa) yêu thích của bạn ra và tạo một tệp mới có tên là helloworld. js. Chúng ta muốn in "Hello World" ra STDOUT, và đây là tất cả những gì chúng ta cần

console.log("Hello World");

Save file back and run it through Node. js

node helloworld.js

Chương trình sẽ trong Hello World ra màn hình thiết bị đầu cuối hoặc dấu nhắc lệnh của bạn

Hơi buồn tẻ một chút phải không?

Một ứng dụng web hoàn toàn chính sử dụng Node. js

Các trường hợp sử dụng

Đơn giản thôi nhưng thực tế

  • Người dùng có thể truy cập vào ứng dụng trên một trình duyệt bất kỳ
  • Người dùng sẽ nhìn thấy một trang chào đón hiển thị một biểu mẫu cho phép tải tệp lên khi truy cập vào địa chỉ http. // tên miền/bắt đầu
  • Sau khi chọn một bức ảnh và nhấn gửi đi, bức ảnh đó sẽ được gửi đến http. //tên miền/tải lên, nơi nó sẽ được hiển thị sau khi quá trình tải lên hoàn tất

Thế là đủ rồi. Bây giờ, bạn có thể đạt được mục tiêu này bằng cách. google và mã sửa đổi của ai đó. Nhưng đó không phải là cách mà chúng ta làm ở đây

Hơn nữa, chúng tôi không muốn viết mã đơn giản nhất có thể để "miễn sao xong là được", cái chúng tôi muốn ở đây là chính xác và rõ ràng nhất có thể. Chúng ta sẽ sử dụng các đối tượng hóa nhiều hơn Mục đích giúp bạn làm quen dần với việc xây dựng các Node ứng dụng. js phức tạp hơn

Constructor of application

Hãy cùng chia nhỏ ứng dụng của chúng ta ra để xem phần nào cần được thực hiện để đạt yêu cầu đã đề ra (trường hợp sử dụng)

  • Chúng ta muốn cho phép người dùng truy cập vào các trang web, vì thế chúng ta cần một máy chủ HTTP
  • Máy chủ của chúng ta phải phản hồi/trả lời các yêu cầu khác nhau, tùy thuộc vào địa chỉ (URL) nào được yêu cầu, vì chúng ta có thể cần cái gì đó có chức năng giống như bộ định tuyến (cầu nối/dẫn)
  • Để trả lời các yêu cầu đã nhận được ở phía máy chủ và đã được dẫn hướng thông qua bộ định tuyến, chúng ta cần các trình xử lý yêu cầu là sự thật.
  • Chắc chắn rằng bộ định tuyến của chúng ta sẽ xử lý tất cả các dữ liệu được gửi đến qua phương thức POST rồi gửi nó đi theo một định dạng thuận tiện cho những người xử lý yêu cầu, vì thế chúng ta cần xử lý dữ liệu yêu cầu. (Có thể hiểu là xử lý dữ liệu đầu vào)
  • Chúng ta không chỉ muốn quản lý các yêu cầu theo đường dẫn mà vẫn hiển thị nội dung khi một đường dẫn nào được gọi, điều này có nghĩa là chúng ta cần một chế độ xem logic mà trình xử lý yêu cầu có thể sử dụng để gửi lại nội dung về
  • Cuối cùng, người dùng có thể tải ảnh lên, vì họ cần bước xử lý tải lên để xử lý việc tải lên

Hãy dành một chút thời gian để suy nghĩ xem chúng ta sẽ xây dựng cấu trúc này với PHP như thế nào. Không quá khó để đoán ra, biến cấu hình phổ biến sẽ là máy chủ web Apache và mod_php5.
Điều này đồng nghĩa với việc nhận, gửi và xử lý các yêu cầu không xảy ra trong bản thân PHP.

Với nút. js thì khác. Bởi vì chúng ta không chỉ viết ứng dụng mà còn cả máy chủ HTTP. Web thực tế, web ứng dụng của chúng ta và web máy chủ của nó về cơ bản giống nhau

Có vẻ như có rất nhiều việc phải làm, nhưng lát nữa bạn sẽ thấy với Node. js, mọi thứ không quá khó đến vậy

Hãy cùng bắt đầu từ vạch xuất phát và viết phần đầu tiên trong cấu trúc của ứng dụng của chúng ta, máy chủ HTTP

Xây dựng cấu trúc ứng dụng

Một máy chủ HTTP cơ bản

Ở cái thời điểm mà tôi muốn bắt đầu phát triển Node ứng dụng. js có tính thực tế đầu tiên của tôi, tôi không chỉ mê mẩn xem phát triển nó như thế nào mà còn tổ chức nó ra làm sao.
Tôi có nên viết tất cả vào một tệp không? . js cơ bản đồng đều tất cả vào một chỗ. Vì vậy nếu tôi muốn chắc chắn rằng mã của tôi luôn rõ ràng và dễ hiểu khi ứng dụng của tôi ngày một mở rộng thì sao?

Hóa ra, cũng không quá khó để phân biệt những thứ không liên quan đến nhau ra, và sắp xếp chúng vào các mô-đun khác nhau

Cách này cho phép chúng ta giữ được tệp chính (tệp khởi động ứng dụng) và các mô-đun luôn rõ ràng, dễ đọc, dễ bảo trì và các mô-đun còn có thể được sử dụng lại ở nhiều nơi khác nhau

Bây giờ hãy tạo một tệp chính, nơi khởi động ứng dụng và một mô-đun tệp chứa mã nguồn cho máy chủ HTTP

Theo quan điểm cá nhân của tôi, tiêu chuẩn để đặt tên tệp chính phải là chỉ mục. js and it will make up the name module host server. js trở nên hợp lý và logic hơn

Hãy cùng bắt đầu viết mô-đun cho máy chủ. Tạo máy chủ tệp mới. js trong thư mục gốc của dự án của bạn, và viết vào đoạn mã sau

var http = require("http");

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

Chỉ thế thôi. Bạn vừa viết xong một máy chủ HTTP có khả năng hoạt động tốt. Hãy xác nhận lại công việc đó bằng cách chạy và kiểm tra nó. Đầu tiên, hãy chạy lệnh sau bằng Node. js

node server.js

Bây giờ hãy mở trình duyệt của bạn ra và truy cập vào địa chỉ sau http. //máy chủ cục bộ. 8888/. Nếu đúng như mong đợi, thứ chúng ta thấy sẽ là "Xin chào thế giới"

Vị trí thú vị phải không? . Tôi sẽ hứa hẹn sẽ cập nhật lại cho nó trong những phần tiếp theo

Phân vùng máy chủ HTTP

Chúng ta hãy cùng phân tích xem nó hoạt động như thế nào

Dòng đầu tiên khai báo (chính xác hơn là yêu cầu, giống với nhập và sử dụng) rằng chúng ta sẽ sử dụng mô-đun http có sẵn trong Node. js vào trong ứng dụng và sẽ gọi nó thông qua biến thông số có tên http

Tiếp theo chúng ta sẽ gọi một trong các chức năng có sẵn của mô-đun http. tạo máy chủ. Hàm này sẽ trả về một đối tượng, đối tượng này chứa một hàm/phương thức khác được gọi là lắng nghe, hàm này nhận vào một số kiểu tham số để sử dụng cổng lắng nghe cho máy chủ HTTP

Bạn đừng chú ý gì đến cái hàm được khai báo sau dấu mở ngoặc của hàm http. tạo máy chủ

Chúng ta đã có thể viết mã để khởi động máy chủ của chúng ta ở cổng 8888 như sau

var http = require("http");

var server = http.createServer();
server.listen(8888);

Đoạn mã này sẽ khởi động một máy chủ HTTP, lắng nghe ở cổng 8888 nhưng không làm gì cả (thậm chí không trả lời các yêu cầu được gửi tới)

Điều thực sự thú vị (hơi buồn cười nếu như bạn đã biết về PHP) ở đây chính là phần định nghĩa/khai báo của hàm được sử dụng ở đâu mà đúng ra nó phải là một tham số cho createServer()

Hóa ra, định nghĩa hàm kia lại chính là giá trị đầu tiên (và duy nhất) mà chúng ta truyền cho lời gọi hàm createServer(). Bởi vì trong JavaScript, hàm có thể được sử dụng như là tham số đầu vào

Về cách sử dụng hàm

Ví dụ, bạn có thể viết như sau

function say(word) {
  console.log(word);
}

function execute(someFunction, value) {
  someFunction(value);
}

execute(say, "Hello");

Hãy đọc thật kỹ. Cái chúng ta viết ở đây là, hàm nói được sử dụng như là tham số đầu vào để hàm thực thi. Không phải giá trị trả về của bạn nói, mà chính bản thân nó

Vì thế, nói trở thành biến nội bộ someFunction trong hàm thực thi, và thực thi có thể gọi bất kỳ hàm nào trong biến someFunction bằng cách gọi hàm (biến) đó (bằng cách thêm dấu trích)

Tất nhiên, vì say nhận một tham số đầu vào, thực thi cũng có thể truyền một tham số tương tự như thế khi gọi hàm someFunction

Chúng ta có thể làm, chúng ta đã làm, là sử dụng hàm như một tham số đầu vào cho hàm khác bằng cách sử dụng tên của chúng. Nhưng, chúng ta không nhất thiết phải đi theo hướng của vòng vo thế này, từ định nghĩa rồi mới đến cách sử dụng - chúng ta có thể kết hợp hai bước này lại với nhau ở một vị trí/thời điểm chung

function execute(someFunction, value) {
  someFunction(value);
}

execute(function(word){ console.log(word) }, "Hello");

Chúng ta định nghĩa hàm muốn thực thi ở ngay chính nơi chúng ta truyền tham số đầu vào

Với cách này, chúng ta thậm chí không cần phải đặt tên cho hàm đó, nó còn được biết đến với cái tên hàm vô danh (hàm ẩn danh)

Đây mới chỉ là thoáng qua cái chúng ta gọi là JavaScript "nâng cao", đừng nóng vội, chúng ta sẽ làm quen với nó từng bước. Xin tạm thời nhập rằng trong JavaScript chúng ta có thể sử dụng hàm như là một tham số đầu vào cho một hàm khác. Chúng ta có thể gán hàm đó vào một biến nào đó hoặc định nghĩa đồng thời với hàm mà chúng ta muốn truyền vào

Sử dụng chức năng như vậy giúp máy chủ HTTP của chúng tôi hoạt động như thế nào

Với những gì bạn vừa học được, hãy quay lại và cải tiến tiến trình máy chủ HTTP của chúng tôi

var http = require("http");

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

Đến bây giờ thì mọi thứ như đã được làm sáng tỏ, thực sự cái chúng ta đang làm là truyền cho hàm tạoServer một hàm vô danh

Chúng ta cũng có thể đạt được kết quả tương tự với đoạn mã sau

________số 8

It could now now to the better time point for question. Tại sao chúng ta lại thực hiện theo cách đó?

Reversed no non bộ dựa trên sự kiện

Để hiểu được tại sao các ứng dụng sử dụng Node. js lại phải viết theo cách như vậy, chúng ta cần hiểu cách Node. js thực thi mã như thế nào. Không phải duy nhất Node. js tiếp cận vấn đề bằng phương pháp này, mỗi mô hình thực thi mã cơ bản (mô hình thực thi cơ bản) khác nhau ở từng môi trường chạy (môi trường thời gian chạy) như Python, Ruby, PHP, hay Java

Hãy cùng xem đoạn mã đơn giản dưới đây

var result = database.query("SELECT * FROM hugetable");
console.log("Hello World");

Hãy tạm thời bỏ qua các tương tác với cơ sở dữ liệu mà chúng ta chưa đề cập đến - đây chỉ là ví dụ mà thôi. Dòng đầu truy vấn đến cơ sở dữ liệu và có thể trả về rất nhiều bản ghi, dòng thứ hai đơn giản chỉ trong màn hình "Hello World"

Giả sử thao tác đến cơ sở dữ liệu diễn ra rất chậm, có rất nhiều bản ghi vui lòng yêu cầu, thời gian thực thi có thể mất vài giây

Với cách mà chúng ta đang làm, trình biên dịch (thông dịch viên) JavaScript của Node. js trước tiên sẽ phải đợi khi thao tác tới cơ sở dữ liệu hoàn tất, sau đó mới thực thi lệnh console. nhật ký()

Nếu đoạn mã này được viết bằng PHP, nó cũng sẽ được thực thi tương tự. đầu tiên là chờ đợi và đọc tất cả các kết quả trả về, sau đó mới thực thi dòng tiếp theo. Nếu đoạn mã này là một phần của trang web, thời gian tải trang mà người dùng phải chờ có thể tăng lên vài giây

Tuy nhiên, trong mô hình thực thi của PHP thì đó không phải là vấn đề đáng quan tâm. máy chủ web PHP khởi tạo một quy trình riêng cho từng yêu cầu mà nó nhận được. Nếu một trong những yêu cầu này chậm hơn bình thường, nó chỉ có thể ảnh hưởng đến thời gian tải trang của người tạo ra yêu cầu đó, chứ không gây ảnh hưởng đến những người dùng khác

Mô hình thực thi của Node. js không giống như vậy - nó chỉ sử dụng duy nhất một quy trình. Nếu truy vấn tới bất kỳ cơ sở dữ liệu nào tốn nhiều thời gian, nó sẽ làm chậm toàn bộ quá trình - mọi thứ sẽ bị dừng lại cho đến khi truy vấn kia kết thúc

Để tránh tình trạng này xảy ra, JavaScript và Node. js đưa ra khái niệm "dựa theo sự kiện" (hướng sự kiện), gọi ngược không đồng bộ (gọi lại không đồng bộ), bằng cách sử dụng một " Vòng lặp sự kiện" (vòng lặp sự kiện)

Chúng ta sẽ hiểu rõ khái niệm này hơn bằng cách phân tích phiên bản đã được cải thiện của ví dụ vừa rồi.

node helloworld.js
0

At here, instead of queue database. query() trực tiếp trả về kết quả, chúng ta truyền nó như là một tham số, hay nói cách khác là một hàm vô danh

Trong phiên bản cũ, mã của chúng ta được thực hiện theo cách "đồng bộ". (1) truy vấn trước cơ sở dữ liệu trước, chỉ sau khi truy vấn này hoàn tất, (2) (2) mới thực hiện lệnh trong màn hình

Now now Node. js has could handle problems to database one way not dong bộ. Cơ sở dữ liệu giả sử. query() được cung cấp bởi một thư viện chuyên xử lý không đồng bộ (thư viện không đồng bộ), Node. js will handle as after. cũng giống như trước, nó sẽ gửi truy vấn tới cơ sở dữ liệu. Nhưng, thay vì chờ đợi kết quả khi truy vấn đó kết thúc, nó sẽ ghi nhớ rằng "Đến một thời điểm nào đó trong tương lai - khi truy vấn kết thúc, kết quả được trả về - nó sẽ phải thực hiện những gì đạt được . truy vấn())" kia

Lúc đó nó sẽ ngay lập tức thực thi giao diện điều khiển. log(), và sau đó bắt đầu một vòng lặp vô tận, và cứ thế mà chờ đợi, không xử lý bất kỳ điều gì khác cho đến khi có một sự kiện nào đó đánh thức nó, ví dụ như truy vấn đến cơ sở dữ liệu đã có

Điều này cũng giải thích cho công việc tại sao máy chủ HTTP của chúng ta cần một hàm để nó có thể gọi tới khi nhận được yêu cầu - if Node. js khởi động rồi dừng lại để chờ yêu cầu khác, chỉ tiếp tục khi nhận được yêu cầu mới thì sẽ rất kém hiệu quả. Nếu bất kỳ người dùng thứ hai nào gửi yêu cầu lên trong khi máy chủ của họ vẫn đang xử lý yêu cầu thứ nhất, thì yêu cầu thứ hai chỉ có thể được xử lý sau khi hoàn thành yêu cầu thứ nhất - có nghĩa là chỉ ngay khi bạn

Có điều quan trọng bạn phải ghi nhớ là mô hình thực thi không đồng bộ, đơn luồng và dựa trên điều kiện này không phải thứ gì đó hoàn toàn tuyệt vời đối với. Nó chỉ là một trong nhiều mô hình đang tồn tại, nó cũng có những nhược điểm, một số trong đó chính là. nó chỉ có thể chạy trên một nhân của CPU mà thôi. Cá nhân tôi cho anh chàng, mô hình này chấp nhận được (có thể tiếp cận), bởi vì họ có thể sử dụng nó để xây dựng các ứng dụng "thời gian thực" (đồng thời) có hiệu quả cao mà không mấy khó khăn

Bạn có thể giành được thời gian đọc thêm bài viết tuyệt vời của nút Hiểu biết của Felix Geisendörfer. js để hiểu sâu hơn về Node. js cũng giống như cách thức hoạt động của nó

Please try a vài ví dụ với khái niệm mới này xem sao. Chúng ta có thể chắc chắn rằng mã của chúng ta vẫn hoạt động tốt sau khi đã tạo máy chủ hay không?

node helloworld.js
1

Chú ý là tôi sử dụng bảng điều khiển. log để hiển thị chuỗi màn hình mỗi khi onRequest được gọi và một chuỗi khác ngay sau khi khởi động máy chủ HTTP

Khi chúng ta chạy lệnh (máy chủ nút. js, như thường lệ), nó sẽ hiển thị trong màn hình "Máy chủ đã khởi động. " ngay lập tức. Và mỗi khi chúng ta gửi yêu cầu đến máy chủ (bằng cách truy cập vào http. //máy chủ cục bộ. 8888/ trên trình duyệt), thông báo "Đã nhận được yêu cầu. " sẽ được hiển thị trên màn hình bảng điều khiển

"JavaScript phía máy chủ không đồng bộ hướng sự kiện với các lệnh gọi lại đang hoạt động". -)

(Lưu ý là máy chủ sẽ hiển thị thông báo. "Yêu cầu đã được nhận. " ra STDOUT (màn hình/bàn điều khiển) hai lần mỗi khi một trang nào đó được truy cập. Do multi number browser send two request, in that one is http. //máy chủ cục bộ. 8888/favicon. ico (biểu tượng nhỏ của mỗi trang nếu có) và bản thân trang http. //máy chủ cục bộ. 8888/)

Máy chủ xử lý yêu cầu như thế nào

Hãy cùng phân tích nhanh phần mã còn lại của máy chủ, phần nội dung của hàm gọi ngược onRequest()

Khi hàm gọi ngược onRequest() được gọi bởi một sự kiện nào đó, hai tham số. yêu cầu và phản hồi sẽ được truyền vào cho nó

Chúng là các đối tượng (object), bạn có thể sử dụng các hàm của chúng để xử lý các chi tiết của yêu cầu HTTP đã nhận và phản hồi lại các yêu cầu đó (ví dụ như, trả về dữ liệu gì đó cho trình duyệt

Và đoạn mã của chúng ta thực hiện. Mỗi khi nhận được yêu cầu, nó gọi hàm phản hồi. writeHead() to write a status code at number. 200 cũng như loại/kiểu nội dung sẽ được gửi về trong đoạn đầu (tiêu đề) của phản hồi và sử dụng hàm phản hồi. write() to write string "Hello World" into the content section of phản hồi (phản hồi HTTP)

Cuối cùng, chúng ta sử dụng phản hồi. end() to default end()

Cho đến thời điểm này, chúng ta vẫn chưa sử dụng đến yêu cầu tham số

Nơi lưu trữ module máy chủ

Như tôi đã hứa trước là chúng tôi sẽ quay lại với chủ đề. làm thế nào để tổ chức ứng dụng tốt của chúng ta. Chúng ta đã hoàn thành một web máy chủ hết sức đơn giản và được lưu vào máy chủ tệp. js, như tôi đã đề cập, mọi người thường đặt tên chỉ mục. js cho tệp chính của ứng dụng, tệp này có nhiệm vụ "mồi" và sau đó khởi động ứng dụng của chúng bằng cách sử dụng các mô-đun (ví dụ như máy chủ mô-đun. js of them ta)

Hãy cùng xem như thế nào để biến máy chủ. js trở thành một module thực sự của Node. js which can be used for file index. js sắp được viết của chúng ta

Có thể bạn đã nhận ra là chúng ta đã sử dụng mô-đun ở đoạn mã của chúng ta

node helloworld.js
2

Ở đâu đó bên trong Node. js, có một mô-đun được gọi là "http", vì thế chúng ta mới có thể sử dụng nó bằng cách tham chiếu đến và gán nó cho một biến nội bộ trong chương trình của chúng ta

Cách này giúp chúng ta sử dụng được tất cả các hàm được cung cấp công khai của đối tượng hoặc mô-đun http giống như bất kỳ đối tượng nào khác

Thói quen tốt để ghi nhớ là đặt tên các biến nội bộ trùng với tên của mô-đun, mặc dù về mặt lý thuyết bạn có thể đặt tên biến tự do

node helloworld.js
3

Bây giờ việc sử dụng các mô-đun mà các mô-đun có sẵn của Node. js đã trở nên dễ dàng. Do đó, có thể làm gì để chúng tôi tạo ra các mô-đun riêng của chúng tôi và sử dụng chúng như thế nào?

Hãy cùng trả lời câu hỏi đó bằng cách biến máy chủ. js trở thành một mô-đun thực sự

Thật ra thì chúng ta không được thay đổi nhiều lắm. Biến một đoạn mã thành một mô-đun có nghĩa là chúng ta phải trích xuất (xuất) một phần chức năng mà chúng ta muốn (từ một tệp bất kỳ đó, hay cả tệp) để đưa vào mô-đun kia

Bây giờ, chức năng của máy chủ web cần được xuất ra rất đơn giản. đó là những gì cần và đủ để khởi động máy chủ

To could make this thing, we we say end all code back to in a function start, then will export it ra

node helloworld.js
4

Theo cách này, bây giờ chúng ta có thể tạo chỉ mục chính của tệp mới. js và khởi động ứng dụng của chúng tôi trong đó, mặc dù tất cả mã cần thiết để chạy máy chủ nằm ở máy chủ tệp. js

Tạo chỉ mục tệp mới. js with after content

node helloworld.js
5

Như bạn thấy, chúng ta có thể sử dụng mô-đun máy chủ giống như bất kỳ mô-đun nào tích hợp sẵn khác trong Node. js. Bằng cách tham chiếu đến tệp đó và gán nó vào một biến nội bộ nào đó, bất kỳ hàm nào được cung cấp một cách công khai (xuất) là chúng ta có thể gọi là được

Xong rồi đó. Bây giờ chúng ta có thể chạy ứng dụng của chúng ta thông qua tệp index. js, and also for results

node helloworld.js
6

Tuyệt vời, giờ chúng ta đã có thể bố trí các thành phần khác nhau trong ứng dụng của chúng ta ra từng tệp riêng biệt và kết nối chúng lại với nhau thông qua thông qua việc tạo mô-đun

Khả năng duy nhất mà ứng dụng của chúng ta có thể thực hiện được cho đến lúc này là. nhận yêu cầu. Nhưng việc chúng ta còn phải làm nữa là xử lý các yêu cầu đó - mỗi yêu cầu cần được xử lý hoàn toàn khác nhau

Đối với những ứng dụng đơn giản, bạn có thể xử lý vấn đề này trực tiếp bên trong hàm gọi ngược onRequest(). Nhưng như tôi đã nói, chúng ta sẽ áp dụng nhiều hiện tượng hóa để làm cho ứng dụng này trở nên thú vị hơn

Hướng cho các yêu cầu khác nhau trỏ tới các phần khác nhau trong ứng dụng của chúng ta được gọi là "điều hướng" (định tuyến) - vậy nên, hãy cùng tạo một mô-đun mới có tên bộ định tuyến

Cần những gì để điều hướng các yêu cầu?

Chúng ta cần có khả năng cung cấp cho "bộ định tuyến" địa chỉ của yêu cầu nhận được và có thể tham số bổ sung như GET hoặc POST, và dựa trên những thông tin này bộ định tuyến cần có khả năng quyết định được xem đoạn mã nào . tập hợp các thành phần xử lý yêu cầu mà thực hiện các yêu cầu được yêu cầu)

Vì thế, chúng ta cần tìm hiểu thêm bên trong một yêu cầu HTTP và phân tách địa chỉ được yêu cầu cũng như tham số GET/POST. Có người cho rằng đây là một phần của bộ định tuyến nhưng cũng có người khác tin rằng nó là một phần của máy chủ (hay thậm chí là một mô-đun độc lập), nhưng tạm thời cho nó là một phần của máy chủ (máy chủ HTTP)

Tất cả thông tin chúng ta cần đều có trong yêu cầu đối tượng, được truyền vào là tham số đầu tiên của hàm gọi ngược onRequest(). Nhưng để biên dịch được những thông tin này, chúng ta cần thêm một số mô-đun bổ sung của Node. js, cụ thể là url và chuỗi truy vấn

url mô-đun cung cấp các phương thức cho phép chúng ta trích xuất các thành phần khác nhau của một địa chỉ URL (ví dụ như. địa chỉ yêu cầu và các truy vấn đi kèm (chuỗi truy vấn) ), và chuỗi truy vấn mô-đun được sử dụng để phân tích cú pháp của các yêu cầu địa chỉ để lấy các tham số

node helloworld.js
7

Đương nhiên là chúng ta cũng có thể sử dụng chuỗi truy vấn để phân tích phần nội dung của một yêu cầu dạng POST để lấy ra các tham số, sẽ đề cập đến phần sau

Please bổ sung logic cần thiết cho hàm onRequest() để tìm đường dẫn nào được yêu cầu

node helloworld.js
8

Tốt rồi, chương trình của chúng ta bây giờ có thể phân biệt được các yêu cầu (request) dựa trên đường dẫn được yêu cầu - việc này cho phép chúng ta "nối" (map) được các yêu cầu đến nơi chúng ta xử lý

Riêng với ứng dụng này, đơn giản là chúng ta chỉ có hai yêu cầu /start và /upload. Chúng ta sẽ xem nó kết hợp với nhau như thế nào ngay thôi

Đã đến lúc để viết bộ định tuyến của chúng tôi. Tạo mới một tệp có tên bộ định tuyến. js with after content

node helloworld.js
9

Tuy đoạn mã này không làm gì cả, nhưng tạm thời cứ như vậy. Vui lòng xem kết nối của bộ định tuyến này với máy chủ (máy chủ HTTP) của chúng ta như thế nào trước đó

Máy chủ HTTP cần phải "nhận định dạng" và "tương tác" với bộ định tuyến. Chúng ta có thể "định" (cố định) sự phụ thuộc này vào máy chủ, tuy nhiên vì đã có kinh nghiệm về lập trình nên chúng ta sẽ kết nối chúng với nhau theo cách linh hoạt hơn (cặp đôi lỏng lẻo) bằng

Trước tiên hãy phát triển hàm start() của máy chủ để đảm bảo rằng chúng ta có thể gọi hàm thông qua tham số (chính xác hơn là điều hướng đến hàm muốn gọi)

var http = require("http");

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

0

Viết thêm vào mục lục tệp. js sao cho tương ứng, đây chính là bước điều hướng hàm trong bộ định tuyến từ máy chủ

var http = require("http");

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

1

Chúng ta sẽ truyền lại hàm đi, việc không có gì lạ cho đến giờ phút này

If they ta run program (node ​​index. js, như thường lệ), và gửi đi một yêu cầu, thì bây giờ chúng ta sẽ thấy máy chủ đã sử dụng bộ định tuyến để truyền đi đường dẫn được yêu cầu

var http = require("http");

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

2

(Tôi đã xóa đi những dòng không cần thiết của yêu cầu tới tệp /favicon. ico)

Thực thi và thực thi

Một lần nữa, xin cho phép tôi có đôi lời tản mạn về "lập trình chức năng"

Sự trao đổi/truyền (chuyển) trực tiếp các chức năng không chỉ là một khái niệm mang tính kỹ thuật. Trong lĩnh vực thiết kế phần mềm, nó gần như còn mang tính học thần kinh. thử nghĩ xem. trong chỉ mục tệp, chúng có thể truyền đối tượng bộ định tuyến cho máy chủ và máy chủ có thể gọi đến hàm tuyến đường của bộ định tuyến đó

Theo cách này, chúng ta đã truyền một thứ, và máy chủ đã sử dụng thứ này để làm một cái gì đó. "Này, bộ định tuyến, bạn có thể vui lòng định tuyến cái này cho tôi không?"

Nhưng máy chủ không cần thứ đó. Nó chỉ cần làm một công việc gì đó. To make done a anything, you don't need a second, what you need to a hành động. You don't need what what you know must do what

Hiểu được cốt lõi cốt lõi của sự thay đổi cơ bản trong tư tưởng về vấn đề này đã khiến tôi hiểu thực sự hiểu biết về "lập trình chức năng"

Tôi đã hiểu được nó khi đọc kiệt tác này của Steve Yegge Cuộc hành quyết ở Vương quốc Danh từ. You should read it. Đó thực sự là một trong những bài viết tuyệt vời nhất về lĩnh vực phần mềm mà tôi đã từng đọc qua

Sự điều hướng yêu cầu tới trình xử lý yêu cầu

Quay trở lại bài viết. Máy chủ HTTP và bộ định tuyến hiện đang tương tác với nhau theo nhịp điệu đúng như mong đợi

Tất nhiên, thế chưa phải là đủ. "Điều hướng" (định tuyến) có nghĩa là, chúng ta muốn điều khiển các yêu cầu (có đường dẫn khác nhau) theo một cách riêng biệt. Chúng ta muốn nghiệp vụ xử lý cho /start split with /upload

Bây giờ, quá trình điều hướng đã "kết thúc" trong bộ định tuyến, và bộ định tuyến không phải là nơi để "làm" bất cứ điều gì theo yêu cầu, bởi vì đó không phải là cách tốt để mở rộng khi ứng dụng trở nên phức tạp hơn

Hãy gọi hàm mà yêu cầu được điều hướng tới là trình xử lý yêu cầu (Không nhận, xử lý "một" yêu cầu nào đó). Và đó là cái chúng ta sẽ cùng đề cập tiếp theo, vì nếu không bạn sẽ không hiểu những gì mà chúng ta sắp thực hiện bên trong router ngay bây giờ