Tìm Hiểu Express.js và Lập Trình Đồng Bộ – Bất Đồng Bộ Trong Node.js
- 08-05-2026
- Toanngo92
- 0 Comments
Mục lục
Giới thiệu
Khi bắt đầu học lập trình backend với Node.js, hai kiến thức cực kỳ quan trọng mà bất kỳ lập trình viên nào cũng cần nắm là:
- Framework Express.js
- Cơ chế lập trình đồng bộ (Synchronous) và bất đồng bộ (Asynchronous)
Đây là nền tảng để xây dựng web server, API và các ứng dụng backend hiện đại với Node.js.
Express.js là gì?
Express.js là một framework tối giản dành cho Node.js, giúp lập trình viên xây dựng web application và API nhanh chóng hơn.
Framework này hỗ trợ:
- Xử lý request/response
- Tạo routing
- Middleware
- Phục vụ static files
- Kết nối template engine
- Xây dựng REST API
Express.js được sử dụng rất phổ biến vì:
- Dễ học
- Nhẹ
- Linh hoạt
- Hiệu năng tốt
- Có cộng đồng lớn
Kiến trúc của Express.js
Express.js thường được tổ chức theo mô hình MVC:
1. View (Application Layer)
Là phần giao diện hiển thị cho người dùng.
Ví dụ:
- HTML
- EJS
- Pug
- Handlebars
2. Controller (Service Layer)
Đóng vai trò xử lý logic giữa View và Model.
Ví dụ:
- Nhận dữ liệu từ form
- Xử lý đăng nhập
- Kiểm tra dữ liệu
3. Model (Data Access Layer)
Làm việc với dữ liệu và database.
Ví dụ:
- MySQL
- MongoDB
- PostgreSQL
Cách hoạt động của Express.js
Quá trình hoạt động cơ bản:
- Server nhận request
- Router xử lý URL
- Middleware kiểm tra dữ liệu
- Handler function xử lý logic
- Trả response về client
Express.js hỗ trợ rất tốt việc xử lý middleware và routing nên giúp source code rõ ràng và dễ bảo trì hơn.
Cài đặt Express.js
Bước 1: Cài Node.js
Tải Node.js từ trang chính thức.
Bước 2: Tạo project
mkdir myapp
cd myapp
Bước 3: Khởi tạo package
npm init -y
Bước 4: Cài Express.js
npm install express
Bước 5: Kiểm tra
npm ls express
Request và Response trong Express.js
Request Object
Đối tượng request dùng để nhận dữ liệu từ client.
Một số thuộc tính phổ biến:
- req.body
- req.headers
- req.params
- req.query
- req.method
- req.url
Response Object
Đối tượng response dùng để gửi dữ liệu về client.
Một số method phổ biến:
- res.send()
- res.json()
- res.render()
- res.redirect()
- res.status()
GET và POST Method
GET
Dùng để lấy dữ liệu.
Ví dụ:
app.get("/", (req, res) => {
res.send("Hello World");
});
GET:
- Dữ liệu nằm trên URL
- Không phù hợp dữ liệu nhạy cảm
- Có thể bookmark
POST
Dùng để gửi dữ liệu lên server.
Ví dụ:
app.post("/login", (req, res) => {
res.send("Login Success");
});
POST:
- Dữ liệu nằm trong body
- Bảo mật hơn
- Thường dùng với form
Đồng bộ và Bất đồng bộ trong Node.js
Một điểm rất đặc biệt của Node.js là cơ chế xử lý bất đồng bộ (Asynchronous Programming).
Lập trình đồng bộ (Synchronous)
Là cách thực thi tuần tự:
- Task sau phải đợi task trước hoàn thành
- Có thể gây block chương trình
Ví dụ:
console.log("Task 1");
console.log("Task 2");
console.log("Task 3");
Kết quả:
Task 1
Task 2
Task 3
Lập trình bất đồng bộ (Asynchronous)
Cho phép nhiều tác vụ chạy mà không chặn chương trình.
Phù hợp với:
- Đọc file
- Gọi API
- Database
- Network request
Ví dụ:
setTimeout(() => {
console.log("Task Async");
}, 2000);
console.log("Task Main");
Kết quả:
Task Main
Task Async
So sánh Đồng bộ và Bất đồng bộ
| Asynchronous | Synchronous |
|---|---|
| Non-blocking | Blocking |
| Chạy nhiều task | Chạy tuần tự |
| Responsive tốt | Có thể gây treo |
| Phù hợp I/O | Phù hợp xử lý đơn giản |
Callback trong Node.js
Callback là function truyền vào function khác.
Ví dụ:
function hello(callback) {
console.log("Hello");
callback();
}
hello(() => {
console.log("Done");
});
Callback giúp xử lý asynchronous nhưng dễ gây:
- Callback Hell
- Code khó đọc
Promise trong Node.js
Promise giúp quản lý asynchronous tốt hơn.
Promise có 3 trạng thái:
- Pending
- Fulfilled
- Rejected
Ví dụ:
const promise = new Promise((resolve, reject) => {
resolve("Success");
});
promise.then(data => {
console.log(data);
});
Async/Await
Đây là cách hiện đại nhất để xử lý asynchronous.
async
Khai báo function bất đồng bộ.
await
Đợi Promise hoàn thành.
Ví dụ:
async function test() {
const data = await Promise.resolve("Hello");
console.log(data);
}
test();
Ưu điểm:
- Dễ đọc
- Code sạch
- Giống synchronous
Event Loop trong Node.js
Event Loop là cơ chế cực kỳ quan trọng của Node.js.
Nhiệm vụ:
- Quản lý asynchronous tasks
- Đảm bảo ứng dụng không bị block
Event Loop liên tục kiểm tra:
- Callback Queue
- Thread Pool
- Event Queue
Để xử lý các tác vụ nền như:
- File system
- Database
- API request
Vì sao Node.js mạnh?
Node.js mạnh vì:
- Non-blocking I/O
- Event Loop
- Hiệu năng cao
- Xử lý nhiều request cùng lúc
- Phù hợp realtime application
Ví dụ:
- Chat app
- API server
- Streaming
- Realtime dashboard
Kết luận
Express.js giúp việc xây dựng backend với Node.js trở nên đơn giản và nhanh chóng hơn rất nhiều.
Trong khi đó, cơ chế asynchronous của Node.js giúp ứng dụng hoạt động hiệu quả, không bị block khi xử lý nhiều request cùng lúc.
Nếu muốn học backend hiện đại, Express.js và Async Programming là hai kiến thức bắt buộc cần nắm vững.
Hướng dẫn
Tạo CSDL mongodb với collection products với các document có các thuọc tính: Product Name, Price , Stock, Action Câu 1: Hiển thị danh sách sản phẩm có điều kiện lọc Tạo tệp index.php và viết mã PHP để hiển thị danh sách tất cả các sản phẩm, được sắp xếp theo giá theo thứ tự giảm dần Khi người dùng nhấp vào “Thêm sản phẩm”, họ sẽ điều hướng đến add_product.php Khi người dùng nhấp vào “chỉnh sửa”, họ sẽ điều hướng đến edit_product.php với tham số chứa id của sản phẩm hiện tại.
Câu 2: Trong tệp add_product.php, Tạo biểu mẫu để nhập thông tin chi tiết về sản phẩm (tên, giá, kho) và xử lý việc chèn vào bảng sản phẩm. Xác thực rằng product_name là duy nhất. Đảm bảo giá lớn hơn 0 và kho ít nhất là 1.
Câu 3: Trong edit_product.php Tạo một biểu mẫu để cập nhật tên, giá và kho của sản phẩm dựa trên id của sản phẩm đó. Đảm bảo id tồn tại trước khi cập nhật. Xác thực rằng product_name là duy nhất. Đảm bảo giá lớn hơn 0 và kho ít nhất là 1. Câu 4: Hiển thị danh sách sản phẩm có nút "Xóa" cho mỗi hàng. Hiển thị cảnh báo xác nhận bằng JavaScript trước khi xóa. Nếu sản phẩm có đơn hàng hiện tại, hãy ngăn chặn việc xóa và thông báo cảnh báo "Không thể xóa sản phẩm vì đã có trong đơn hàng!". Nếu không, hãy xóa sản phẩm khỏi cơ sở dữ liệu

Bài 2:
Phần 1: Kết nối cơ sở dữ liệu MongoDB — 4 điểm
Viết một tệp cấu hình có thể được import vào các tệp Node.js khác. Tệp này phải:
-
Kết nối tới MongoDB bằng thông tin hợp lệ.
-
Sử dụng database tên
abc12. -
Tạo hoặc định nghĩa collection
abc12users. -
Collection
abc12userscần lưu các trường:
username: String
password_hash: String
phone: String
Yêu cầu:
username phải là duy nhất
phone tối đa 10 ký tự
Nếu có lỗi kết nối hoặc thao tác database, chương trình phải dừng và in lỗi rõ ràng
Phần 2: Biểu mẫu đăng ký — 4 điểm
Viết một route Node.js/Express hiển thị form đăng ký gồm 3 trường:
Tên người dùng
Mật khẩu
Số điện thoại
Yêu cầu:
-
Form gửi dữ liệu bằng phương thức
POSTvề chính route đăng ký. -
Trước khi thêm user mới, hệ thống phải kiểm tra username đã tồn tại chưa.
-
Nếu username đã tồn tại, hiển thị thông báo lỗi và form đăng ký trống.
-
Nếu hợp lệ, lưu user vào collection
abc12users. -
Mật khẩu không được lưu dạng plain text, phải lưu dạng hash.
-
Sau khi đăng ký thành công, hiển thị lại:
Tên người dùng
Số điện thoại
Phần 3: Biểu mẫu đăng nhập — 4 điểm
Viết một route Node.js/Express hiển thị form đăng nhập gồm 2 trường:
Tên người dùng
Mật khẩu
Yêu cầu:
-
Form gửi dữ liệu bằng
POSTvề chính route đăng nhập. -
Khi submit, hệ thống kiểm tra username và password với dữ liệu trong MongoDB.
-
Nếu đúng, hiển thị thông báo chào mừng.
-
Nếu sai, hiển thị:
Tên người dùng hoặc mật khẩu không hợp lệ
và hiển thị lại form đăng nhập.
Đầu ra của route đăng nhập chỉ thuộc một trong các trường hợp:
Form đăng nhập
Thông báo chào mừng
Thông báo lỗi + form đăng nhập
Phần 4: Session cho đăng nhập — 4 điểm
Mở rộng chức năng đăng nhập ở phần 3.
Yêu cầu:
-
Khi đăng nhập thành công, tạo session để ghi nhận user đã đăng nhập.
-
Ví dụ:
req.session.loggedin = true
req.session.user = user
-
Khi tải lại trang đăng nhập, nếu user đã đăng nhập thì hiển thị thông báo chào mừng thay vì form đăng nhập.
-
Thêm nút:
Đăng xuất
-
Khi bấm đăng xuất, session bị xóa và người dùng quay lại form đăng nhập.
-
Người dùng vẫn đăng nhập khi refresh trang hoặc mở nhiều tab, nhưng sẽ mất trạng thái đăng nhập khi session hết hạn hoặc trình duyệt đóng.
Phần 5: Remember me — 3 điểm
Bổ sung checkbox:
Remember me
vào form đăng nhập.
Yêu cầu:
-
Nếu checkbox được chọn và đăng nhập thành công, lưu cookie để nhận diện user ở những lần truy cập sau.
-
Khi người dùng đóng trình duyệt rồi mở lại, hệ thống vẫn nhận diện là đã đăng nhập.
-
Cookie cần có thời gian hết hạn hợp lý, ví dụ:
7 ngày
30 ngày
-
Nếu người dùng bấm đăng xuất, cookie remember me phải bị xóa.
Bài 2: Website bán hàng Node.js + MongoDB
Yêu cầu chung — 20 điểm
Xây dựng website bán hàng sử dụng:
Node.js
Express.js
MongoDB
EJS hoặc template engine tương đương
Phần 1: Thiết kế cơ sở dữ liệu — 4 điểm
Tạo các collection sau:
products
users
orders
Collection products cần có tối thiểu các trường:
name: String
price: Number
image: String
description: String
stock: Number
Collection users cần có tối thiểu:
username: String
password_hash: String
phone: String
role: String
Collection orders cần lưu:
user_id
items
total
created_at
Yêu cầu dữ liệu mẫu:
Tạo ít nhất 10 sản phẩm mẫu
Tạo ít nhất 1 tài khoản admin
Phần 2: Trang chủ hiển thị sản phẩm — 4 điểm
Xây dựng trang chủ có giao diện bán hàng.
Yêu cầu:
-
Hiển thị danh sách sản phẩm từ MongoDB.
-
Mỗi sản phẩm cần hiển thị:
Ảnh sản phẩm
Tên sản phẩm
Giá
Mô tả ngắn
Nút thêm vào giỏ hàng
-
Giao diện bố cục rõ ràng, dễ sử dụng.
-
Có menu điều hướng:
Trang chủ
Giỏ hàng
Đăng nhập / Đăng xuất
Admin nếu là tài khoản quản trị
Phần 3: Trang quản trị sản phẩm — 5 điểm
Xây dựng trang admin quản lý sản phẩm.
Chỉ user có role:
admin
mới được truy cập.
Yêu cầu chức năng:
Thêm sản phẩm
Sửa sản phẩm
Xóa sản phẩm
Xem danh sách sản phẩm
Khi thêm/sửa sản phẩm cần nhập:
Tên sản phẩm
Giá
Ảnh
Mô tả
Số lượng tồn kho
Phần 4: Giỏ hàng — 4 điểm
Xây dựng chức năng giỏ hàng.
Yêu cầu:
-
Người dùng có thể thêm sản phẩm vào giỏ hàng.
-
Giỏ hàng lưu trong session.
-
Trang giỏ hàng hiển thị:
Tên sản phẩm
Giá
Số lượng
Tạm tính
Tổng tiền
-
Có chức năng:
Xóa sản phẩm khỏi giỏ hàng
Cập nhật số lượng sản phẩm
Phần 5: Mua hàng / đặt hàng — 3 điểm
Xây dựng chức năng đặt hàng.
Yêu cầu:
-
Người dùng phải đăng nhập mới được đặt hàng.
-
Khi đặt hàng, dữ liệu đơn hàng được lưu vào collection
orders. -
Sau khi đặt hàng thành công:
Xóa giỏ hàng
Hiển thị thông báo đặt hàng thành công

