Callbacks trong Node.js là một loại hàm đặc biệt được truyền như một tham số cho một hàm khác. Callbacks giúp chúng ta thực hiện các lời gọi bất đồng bộ.

Trong bài viết này, chúng ta sẽ cùng tìm hiểu về callbacks trong Node.js, cách sử dụng và ứng dụng của chúng trong các tình huống thực tế.

1. Callback là gì?

Callback là một hàm được gọi khi một sự kiện nào đó xảy ra hay khi một tác vụ nào đó hoàn thành. Callback thường được sử dụng để xử lý kết quả của một hàm bất đồng bộ hoặc để tiếp tục thực hiện các hàm khác sau khi một hàm bất đồng bộ kết thúc.

Một hàm bất đồng bộ là một hàm không chặn (block) luồng thực thi của chương trình mà thay vào đó trả về ngay một giá trị hoặc một đối tượng đại diện cho kết quả sẽ được trả về sau khi hàm hoàn thành. Ví dụ, khi bạn đọc một file bằng hàm fs.readFile trong Node.js, hàm này sẽ không đợi cho đến khi file được đọc xong mà sẽ trả về ngay một đối tượng Promise và tiếp tục thực hiện các hàm khác trong chương trình. Khi file được đọc xong, hàm callback sẽ được gọi với kết quả là nội dung của file hoặc lỗi nếu có.

Callback là một cách phổ biến để xử lý các hàm bất đồng bộ trong Node.js, bởi vì Node.js là một môi trường đơn luồng (single-threaded), nghĩa là chỉ có một luồng thực thi mã trong một thời điểm. Do đó, nếu một hàm chặn luồng thực thi, chẳng hạn như đợi một file được đọc xong, hoặc một yêu cầu mạng được trả lời, thì chương trình sẽ không thể thực hiện các hàm khác, và sẽ bị treo (hang) hoặc chậm (slow). 

Để giải quyết vấn đề này, Node.js sử dụng một cơ chế gọi là vòng lặp sự kiện (event loop), để xử lý các sự kiện bất đồng bộ một cách hiệu quả.

2. Cách sử dụng callback trong Node.js

Để sử dụng callback trong Node.js, bạn có thể tuân theo các bước sau:

  • Bước 1: Tạo một hàm callback, là một hàm nhận một hoặc nhiều tham số, thường là kết quả hoặc lỗi của một hàm bất đồng bộ. Hàm callback có thể được định nghĩa trước, hoặc được viết dưới dạng một hàm vô danh (anonymous function) hoặc một hàm mũi tên (arrow function).
  • Bước 2: Truyền hàm callback như một tham số cho một hàm bất đồng bộ, thường là hàm cuối cùng trong danh sách các tham số. Hàm bất đồng bộ sẽ gọi hàm callback khi nó hoàn thành việc thực thi, và truyền kết quả hoặc lỗi cho hàm callback.
  • Bước 3: Trong hàm callback, kiểm tra xem có lỗi nào được truyền vào không, nếu có thì xử lý lỗi, nếu không thì xử lý kết quả. Bạn có thể sử dụng các câu lệnh điều khiển như if...else, try...catch, hoặc các phương thức của đối tượng Promise như then, catch, finally để xử lý lỗi và kết quả.

>>>>> Xem thêm bài viết tương tự tại đây:

3. Ví dụ về callback trong Node.js

Dưới đây là một ví dụ minh họa cho việc sử dụng callback trong Node.js. Chúng ta sẽ viết một chương trình để đọc nội dung của một file bằng hàm fs.readFile trong module fs của Node.js, và in ra nội dung hoặc lỗi nếu có.

Trước tiên, chúng ta tạo một file văn bản có tên input.txt với nội dung sau:

Đây là một file văn bản để minh họa cho việc sử dụng callback trong Node.js

Tiếp theo, chúng ta tạo một file callback.js với đoạn code sau:

// Nhập module fs
const fs = require('fs');

// Tạo một hàm callback
function readCallback(err, data) {
  // Kiểm tra lỗi
  if (err) {
    // In ra lỗi
    console.error(err);
  } else {
    // In ra nội dung file
    console.log(data.toString());
  }
}

// Đọc file bằng hàm bất đồng bộ và truyền hàm callback
fs.readFile('input.txt', readCallback);

// In ra một dòng khác
console.log('Chương trình kết thúc');

Cuối cùng, chúng ta chạy file callback.js bằng lệnh sau:

node callback.js

Kết quả:

Chương trình kết thúc
Đây là một file văn bản để minh họa cho việc sử dụng callback trong Node.js

Ta có thể thấy rằng, hàm readFile không chặn luồng thực thi của chương trình, mà trả về ngay một đối tượng Promise và tiếp tục thực hiện các hàm khác trong chương trình. Khi file được đọc xong, hàm readCallback được gọi với kết quả là nội dung của file hoặc lỗi nếu có.

4. Ứng dụng của callback trong Node.js

Callback trong Node.js có nhiều ứng dụng trong các tình huống thực tế, như:

  • Xử lý các yêu cầu HTTP từ client, bằng cách sử dụng các hàm callback để trả về kết quả hoặc lỗi cho client. Ví dụ, khi bạn sử dụng module http trong Node.js để tạo một máy chủ web, bạn có thể truyền một hàm callback cho phương thức createServer, hàm này sẽ nhận hai đối số là requestresponse, đại diện cho yêu cầu và phản hồi của client. Bạn có thể sử dụng các phương thức của đối tượng response để gửi dữ liệu, trạng thái, tiêu đề hoặc kết thúc phản hồi cho client.

Dưới đây là một ví dụ minh họa cho việc sử dụng callback để xử lý các yêu cầu HTTP trong Node.js:

// Nhập module http
const http = require('http');

// Tạo một máy chủ web và truyền một hàm callback
const server = http.createServer((request, response) => {
  // Kiểm tra đường dẫn của yêu cầu
  if (request.url === '/') {
    // Gửi trạng thái 200 (OK) và tiêu đề Content-Type
    response.writeHead(200, {'Content-Type': 'text/html'});
    // Gửi dữ liệu là một đoạn HTML
    response.write('<h1>Xin chào, đây là trang chủ</h1>');
    // Kết thúc phản hồi
    response.end();
  } else if (request.url === '/about') {
    // Gửi trạng thái 200 (OK) và tiêu đề Content-Type
    response.writeHead(200, {'Content-Type': 'text/html'});
    // Gửi dữ liệu là một đoạn HTML
    response.write('<h1>Đây là trang giới thiệu</h1>');
    // Kết thúc phản hồi
    response.end();
  } else {
    // Gửi trạng thái 404 (Not Found) và tiêu đề Content-Type
    response.writeHead(404, {'Content-Type': 'text/html'});
    // Gửi dữ liệu là một đoạn HTML
    response.write('<h1>Không tìm thấy trang yêu cầu</h1>');
    // Kết thúc phản hồi
    response.end();
  }
});

// Lắng nghe cổng 3000
server.listen(3000, () => {
  console.log('Máy chủ đang chạy tại http://localhost:3000');
});
  • Thao tác với cơ sở dữ liệu, bằng cách sử dụng các hàm callback để thực hiện các truy vấn, thêm, sửa, xóa dữ liệu và nhận kết quả hoặc lỗi từ cơ sở dữ liệu. 

Ví dụ, khi bạn sử dụng module mongodb trong Node.js để kết nối và làm việc với cơ sở dữ liệu MongoDB, bạn có thể truyền các hàm callback cho các phương thức như connect, find, insertOne, updateOne, deleteOne, v.v… Các hàm callback sẽ nhận kết quả hoặc lỗi từ cơ sở dữ liệu và xử lý theo ý muốn. 

Dưới đây là một ví dụ minh họa cho việc sử dụng callback để thao tác với cơ sở dữ liệu MongoDB trong Node.js:

// Nhập module mongodb
const mongodb = require('mongodb');

// Tạo một đối tượng MongoClient
const MongoClient = mongodb.MongoClient;

// Định nghĩa địa chỉ kết nối
const url = 'mongodb://localhost:27017';

// Định nghĩa tên cơ sở dữ liệu
const dbName = 'test';

// Kết nối với cơ sở dữ liệu và truyền một hàm callback
MongoClient.connect(url, (err, client) => {
  // Kiểm tra lỗi
  if (err) {
    // In ra lỗi
    console.error(err);
  } else {
    // In ra thông báo
    console.log('Kết nối thành công');
    // Lấy đối tượng cơ sở dữ liệu
    const db = client.db(dbName);
    // Lấy đối tượng bộ sưu tập
    const collection = db.collection('users');
    // Thêm một tài liệu vào bộ sưu tập và truyền một hàm callback
    collection.insertOne({name: 'Alice', age: 25}, (err, result) => {
      // Kiểm tra lỗi
      if (err) {
        // In ra lỗi
        console.error(err);
      } else {
        // In ra kết quả
        console.log(result);
      }
      // Đóng kết nối
      client.close();
    });
  }
});
  • Làm việc với các API bên ngoài, bằng cách sử dụng các hàm callback để gửi và nhận dữ liệu từ các API, và xử lý kết quả hoặc lỗi từ các API. 

Ví dụ, khi bạn sử dụng module request trong Node.js để gửi các yêu cầu HTTP đến các API bên ngoài, bạn có thể truyền một hàm callback cho phương thức request, hàm này sẽ nhận ba đối số là error, responsebody, đại diện cho lỗi, phản hồi và nội dung của phản hồi từ API. 

Bạn có thể sử dụng các thuộc tính và phương thức của đối tượng response để kiểm tra trạng thái, tiêu đề, hoặc định dạng của phản hồi và xử lý nội dung của body theo ý muốn.

Dưới đây là một ví dụ minh họa cho việc sử dụng callback để làm việc với API bên ngoài trong Node.js:

// Nhập module request
const request = require('request');

// Định nghĩa địa chỉ của API
const url = 'https://api.openweathermap.org/data/2.5/weather?q=Hanoi&appid=YOUR_API_KEY';

// Gửi một yêu cầu GET đến API và truyền một hàm callback
request.get(url, (error, response, body) => {
  // Kiểm tra lỗi
  if (error) {
    // In ra lỗi
    console.error(error);
  } else {
    // In ra trạng thái và tiêu đề của phản hồi
    console.log('Trạng thái:', response.statusCode);
    console.log('Tiêu đề:', response.headers['content-type']);
    // Chuyển đổi nội dung của phản hồi từ JSON sang đối tượng JavaScript
    const data = JSON.parse(body);
    // In ra nhiệt độ và độ ẩm của thành phố Hà Nội
    console.log('Nhiệt độ:', data.main.temp);
    console.log('Độ ẩm:', data.main.humidity);
  }
});

Tổng kết

Trong bài viết này, chúng ta đã cùng tìm hiểu về callbacks trong Node.js, một loại hàm đặc biệt được truyền như một tham số cho một hàm khác. Hi vọng sẽ giúp ích cho bạn khi làm việc với Node.js.


Stringee Communication APIs là giải pháp cung cấp các tính năng giao tiếp như gọi thoại, gọi video, tin nhắn chat, SMS hay tổng đài CSKH cho phép tích hợp trực tiếp vào ứng dụng/website của doanh nghiệp nhanh chóng. Nhờ đó giúp tiết kiệm đến 80% thời gian và chi phí cho doanh nghiệp bởi thông thường nếu tự phát triển các tính năng này có thể mất từ 1 - 3 năm.

Bộ API giao tiếp của Stringee hiện đang được tin dùng bởi các doanh nghiệp ở mọi quy mô, lĩnh vực ngành nghề như TPBank, VOVBacsi24, VNDirect, Shinhan Finance, Ahamove, Logivan, Homedy, Adavigo, bTaskee…

Quý bạn đọc quan tâm xin mời đăng ký NHẬN TƯ VẤN TẠI ĐÂY

Banner bottom