Giải thích về các lời hứa trong JavaScript: then, Catch, Promise.all và các lỗi thường gặp

  1. Trang chủ
  2. Blog
  3. Phát triển phần mềm

Phát triển phần mềm

Giải thích về lời hứa JavaScript: rồi, bắt, Promise.all và những lỗi thường gặp

Lời hứa là cách JavaScript xử lý công việc kết thúc sau và async/await được xây dựng dựa trên chúng. Tìm hiểu cách chúng thực sự hoạt động, với kết quả thực tế từ mỗi ví dụ và tránh những sai lầm nuốt chửng lỗi của bạn.

Đọc 10 phút
Giải thích các lời hứa trong JavaScript: then, Catch, Promise.all và các lỗi thường gặp

Điểm chính

  • promise là một đối tượng đại diện cho một kết quả sẽ có sau này.
  • Nó đang chờ xử lý cho đến khi được đáp ứng hoặc bị từ chối, và một khi đã được giải quyết thì nó sẽ không bao giờ thay đổi.
  • Mỗi then trả về một lời hứa mới, đó là điều khiến cho việc xâu chuỗi trở nên khả thi.
  • Sử dụng Promise.all khi mọi kết quả đều được yêu cầu và Promise.allSettled khi bạn muốn mọi kết quả.

Tất cả các yêu cầu mạng, đọc tệp và bộ hẹn giờ đều kết thúc sau, nhưng JavaScript không thể chỉ dừng và chờ, nếu không trang sẽ bị treo. Lời hứa JavaScript cung cấp cho bạn một cách ngắn gọn để nói “khi việc này kết thúc, hãy làm việc đó và nếu thất bại, thay vào đó hãy làm việc này”.

Ngay cả khi bạn chủ yếu viết async và await, bạn vẫn đang sử dụng các lời hứa bên dưới, vì vậy việc hiểu chúng sẽ giúp việc gỡ lỗi trở nên dễ dàng hơn nhiều. Chúng tôi đã chạy các ví dụ này trên Node.js 24 và kết quả hiển thị là từ lần chạy đó. Chúng hoạt động theo cách tương tự trong các trình duyệt hiện đại.

Một lời hứa là gì?

Lời hứa là một phần giữ chỗ cho một giá trị trong tương lai. Hãy nghĩ đến chiếc chuông mà nhà hàng đưa cho bạn khi bạn gọi món. Bạn chưa có thức ăn, nhưng bạn cầm một thứ gì đó sẽ cho bạn biết khi nào nó đã sẵn sàng hoặc có vấn đề gì đó, và trong khi đó bạn có thể tự do làm những việc khác.

Trong mã, hàm không đồng bộ trả về lời hứa ngay lập tức và bạn đính kèm điều gì sẽ xảy ra tiếp theo:

fetch("/api/user")
  .then((response) => response.json())
  .then((user) => console.log(user.name))
  .catch((error) => console.log("Failed:", error.message));

Ba trạng thái hứa hẹn

tiểu bang Ý nghĩa Cái gì chạy
Đang chờ xử lý Công việc vẫn chưa kết thúc Chưa có gì
Đã hoàn thành Nó kết thúc với một giá trị then người xử lý
Bị từ chối Nó thất bại có lý do catch người xử lý

Một lời hứa được thực hiện hoặc bị từ chối được gọi là đã giải quyết. Một lời hứa chỉ có thể thực hiện được một lần. Sau đó, trạng thái và giá trị của nó được cố định và các lệnh gọi sau tới resolve hoặc reject sẽ bị bỏ qua.

Tạo một lời hứa

Bạn thường sử dụng các lời hứa từ các API như fetch, nhưng việc tạo một API sẽ cho thấy cách chúng hoạt động. Hàm tạo nhận được hai hàm, resolve và reject:

function fetchUser(id) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (id > 0) {
        resolve({ id, name: "Asha" });
      } else {
        reject(new Error("Invalid id"));
      }
    }, 100);
  });
}

console.log(fetchUser(1));

// Promise { <pending> }

Ghi lại lời hứa ngay lập tức cho thấy nó vẫn đang chờ xử lý vì bộ hẹn giờ chưa kích hoạt. Giá trị chỉ có thể đạt được thông qua trình xử lý hoặc await. Luôn từ chối bằng đối tượng Error thay vì chuỗi, vì Error mang dấu vết ngăn xếp giúp gỡ lỗi.

sau đó, bắt và cuối cùng

Ba phương thức này gắn các trình xử lý vào một lời hứa:

fetchUser(1).then((user) => console.log(user.name));
// Asha

fetchUser(-1)
  .then((user) => console.log("never runs", user))
  .catch((error) => console.log("caught:", error.message))
  .finally(() => console.log("finally"));

// caught: Invalid id
// finally

then chạy khi thành công, catch chạy khi thất bại và finally chạy theo cách nào đó. Điều đó làm cho finally trở thành nơi thích hợp để dọn dẹp, chẳng hạn như ẩn một vòng quay tải. Nó không nhận được sự tranh luận nào, bởi vì nó không nên quan tâm đến kết quả.

Xâu chuỗi lời hứa

Ý tưởng chính là then luôn trả lại lời hứa mới. Bất cứ điều gì trình xử lý của bạn trả về đều trở thành giá trị của lời hứa mới đó:

Promise.resolve(2)
  .then((n) => n * 10)
  .then((n) => n + 1)
  .then((n) => console.log("chain:", n));

// chain: 21

Nếu một trình xử lý trả lại một lời hứa khác, chuỗi sẽ đợi nó ổn định trước khi tiếp tục. Đây là cách biến các cuộc gọi lại lồng nhau thành một chuỗi các bước phẳng:

getUser(id)
  .then((user) => getOrders(user.id))
  .then((orders) => getInvoice(orders[0].id))
  .then((invoice) => console.log(invoice.total))
  .catch(handleError);

Làm thế nào lỗi di chuyển qua một chuỗi

Một lời hứa bị từ chối sẽ bỏ qua mỗi then cho đến khi đạt đến catch. Ném vào bên trong một trình xử lý cũng được tính là từ chối. Và catch quay trở lại bình thường sẽ đưa chuỗi trở lại đúng hướng:

Promise.resolve("start")
  .then(() => {
    throw new Error("step 2 failed");
  })
  .then(() => console.log("skipped"))
  .catch((error) => {
    console.log("caught:", error.message);
    return "recovered";
  })
  .then((value) => console.log("continues:", value));

// caught: step 2 failed
// continues: recovered

Hãy coi đây là phiên bản không đồng bộ của try và catch. Một catch ở cuối thường bao phủ toàn bộ chuỗi. Nếu bạn chỉ muốn ghi lại một lỗi mà vẫn thất bại, hãy ném lại nó từ bên trong catch.

Mẹo: fetch chỉ từ chối khi mạng bị lỗi. Phản hồi 404 hoặc 500 vẫn đáp ứng, vì vậy hãy tự kiểm tra response.ok. Bảng tóm tắt mã trạng thái HTTP của chúng tôi giải thích ý nghĩa của từng mã.

Promise.all, allSettled, chủng tộc và bất kỳ

Các phương thức tĩnh này phối hợp một số lời hứa cùng một lúc. Tất cả đều lấy một mảng và trả lại một lời hứa.

phương pháp Đáp ứng khi Từ chối khi Sử dụng nó cho
Promise.all Tất cả đều đáp ứng Bất cứ ai từ chối Tất cả các kết quả được yêu cầu
Promise.allSettled Tất cả giải quyết không bao giờ Bạn muốn mọi kết quả
Promise.race Người đầu tiên giải quyết hoàn thành Người đầu tiên giải quyết từ chối Hết giờ
Promise.any Việc đầu tiên đáp ứng Tất cả đều từ chối Nguồn thành công đầu tiên

Để kiểm tra chúng, chúng tôi đã sử dụng hai trợ giúp nhỏ, một trợ giúp thành công sau độ trễ và một trợ giúp thất bại sau độ trễ:

const wait = (ms, value) =>
  new Promise((resolve) => setTimeout(() => resolve(value), ms));
const fail = (ms, message) =>
  new Promise((_, reject) => setTimeout(() => reject(new Error(message)), ms));

Promise.all

await Promise.all([wait(300, "a"), wait(100, "b"), wait(200, "c")]);

// [ 'a', 'b', 'c' ]   took about 300 ms

Hai chi tiết cần chú ý. Kết quả giữ nguyên thứ tự đầu vào, mặc dù b đã hoàn thành trước. Và tổng thời gian là khoảng 300 mili giây, thời gian của tác vụ chậm nhất chứ không phải tổng thời gian là 600 mili giây, vì cả ba đều đã chạy cùng một lúc. Nếu bất kỳ ai trong số họ từ chối, toàn bộ sự việc sẽ từ chối ngay lập tức:

await Promise.all([wait(100, "a"), fail(50, "b failed")]);

// rejected: b failed

Promise.allSettled

Điều này chờ đợi mọi thứ và báo cáo từng kết quả, vì vậy một lỗi không làm mất phần còn lại. Nó phù hợp với một bảng điều khiển trong đó mỗi tiện ích tải độc lập:

const results = await Promise.allSettled([wait(50, "a"), fail(50, "b failed")]);
results.map((r) => r.status);

// [ 'fulfilled', 'rejected' ]

Promise.race và Promise.any

await Promise.race([wait(300, "slow"), wait(100, "fast")]);   // fast
await Promise.any([fail(50, "x"), wait(100, "ok")]);          // ok

Sự khác biệt là race lấy người đầu tiên giải quyết, ngay cả khi nó thất bại, trong khi any bỏ qua những thất bại miễn là có điều gì đó thành công. Cách sử dụng cổ điển của race là thêm thời gian chờ cho một yêu cầu chậm, mặc dù tác vụ chậm hơn vẫn tiếp tục chạy ở chế độ nền trừ khi bạn hủy nó.

Lời hứa và không đồng bộ/chờ đợi

async và await là cách dễ đọc hơn để làm việc với cùng một lời hứa. Hàm async luôn trả về một lời hứa và await tạm dừng hàm đó cho đến khi lời hứa được giải quyết:

async function showInvoice(id) {
  try {
    const user = await getUser(id);
    const orders = await getOrders(user.id);
    console.log(orders.length);
  } catch (error) {
    console.log("Failed:", error.message);
  }
}

Việc từ chối trở thành lỗi ném ra, vì vậy try và catch thông thường sẽ hoạt động. Bạn vẫn cần Promise.all để thực hiện công việc song song, vì việc chờ hết cuộc gọi này đến cuộc gọi khác sẽ chạy chúng theo trình tự. Hướng dẫn chờ đợi/không đồng bộ JavaScript của chúng tôi sẽ đi sâu hơn về vấn đề này.

Lời hứa và vòng lặp sự kiện

Người xử lý lời hứa không bao giờ được gọi ngay lập tức, ngay cả khi lời hứa đã được thực hiện. Chúng chạy sau khi mã hiện tại kết thúc và trước bất kỳ bộ tính giờ nào. Đây là bằng chứng:

setTimeout(() => console.log("timeout"), 0);
Promise.resolve().then(() => console.log("microtask"));
console.log("sync");

// sync
// microtask
// timeout

Mã đồng bộ chạy đầu tiên. Tiếp theo là hàng đợi vi nhiệm, chứa các trình xử lý lời hứa. Chỉ khi đó vòng lặp sự kiện mới nhận nhiệm vụ tiếp theo, chẳng hạn như bộ hẹn giờ. Đây là một câu hỏi phỏng vấn phổ biến và nó giải thích tại sao setTimeout bằng 0 không thực sự xuất hiện ngay lập tức.

Lời hứa và cuộc gọi lại

Mối quan tâm Cuộc gọi lại Lời hứa
Trình tự Lồng nhau, sâu hơn ở mỗi bước Một chuỗi phẳng
Lỗi Đã kiểm tra ở mọi cấp độ Một catch có thể bao phủ chuỗi
Công việc song song quầy thủ công Promise.all
Gọi nhầm hai lần? Có thể Không thể giải quyết hai lần

Những lỗi thường gặp

  • Quên quay lại bên trong then. Không có return, bước tiếp theo nhận được undefined và không chờ đợi lời hứa bên trong của bạn.
  • Không catch gì cả. Điều này gây ra sự từ chối không được xử lý và trong Node.js, quy trình này sẽ dừng quá trình theo mặc định.
  • Lồng nhau thay vì xâu chuỗi. Đặt then vào trong then sẽ tạo ra địa ngục gọi lại. Trả lại lời hứa và tiếp tục chuỗi.
  • Gói lời hứa trong new Promise. Nếu một hàm đã trả về một lời hứa thì chỉ cần sử dụng nó.
  • Sử dụng forEach với lệnh gọi lại không đồng bộ. Nó không chờ. Sử dụng for...of hoặc Promise.all với map, như được hiển thị trong hướng dẫn của chúng tôi về các phương thức mảng JavaScript.
  • Suy nghĩ một lời hứa có thể bị hủy bỏ. Tự nó không thể. Đối với các yêu cầu, sử dụng AbortController.

Lời kết

Lời hứa tuân theo một số quy tắc: lời hứa được thực hiện một lần, then trả lại lời hứa mới và lỗi sẽ di chuyển theo chuỗi cho đến khi có thứ gì đó phát hiện được. Một khi những quy tắc đó trở nên tự nhiên, async và await sẽ không còn là phép thuật nữa. Để thực hành, hãy viết lại một hàm dựa trên lệnh gọi lại bằng các lời hứa, sau đó tìm nạp hai điểm cuối bằng Promise.all và xử lý lỗi đúng cách.

Câu hỏi thường gặp

Lời hứa trong JavaScript là gì?

Lời hứa là một đối tượng đại diện cho kết quả cuối cùng của công việc không đồng bộ. Nó bắt đầu ở dạng đang chờ xử lý, sau đó đáp ứng với một giá trị hoặc từ chối kèm theo lý do.

Sự khác biệt giữa sau đó và bắt là gì?

sau đó chạy khi lời hứa được thực hiện và bắt chạy khi từ chối. việc bắt có hiệu quả chỉ với một trình xử lý từ chối và nó cũng có thể bắt các lỗi được đưa ra ở các bước trước đó.

Sự khác biệt giữa Promise.all và Promise.allSettled là gì?

Promise.all từ chối ngay khi một lời hứa từ chối. Promise.allSettled luôn chờ đợi tất cả và báo cáo trạng thái cũng như giá trị hoặc lý do của từng người.

Tôi nên sử dụng lời hứa hay không đồng bộ/chờ đợi?

Họ làm việc cùng nhau vì sự chờ đợi được xây dựng dựa trên những lời hứa. Hầu hết mã đọc tốt nhất với async/await, trong khi Promise.all và các phương thức tương tự vẫn hữu ích cho công việc song song.

Những lời hứa có chạy song song không?

JavaScript chạy từng đoạn mã một trên một luồng nhưng hoạt động giống như các yêu cầu mạng diễn ra ở chế độ nền. Một số trong số này có thể được tiến hành cùng một lúc.

Tiếp tục học hỏi

Làm việc với Stack Quora

Cần trợ giúp về kiểm tra, WordPress hoặc SEO?

Chúng tôi giúp các nhóm phát triển phần mềm tốt hơn và phát triển trang web của họ. Hãy cho chúng tôi biết bạn đang làm gì và chúng tôi sẽ đề xuất bước tiếp theo rõ ràng.

Tiếp tục đọc

Thêm hướng dẫn về thử nghiệm, AI và phát triển hiện đại

Bạn thích bài viết này? Chọn một chủ đề và chuyển ngay sang phần hướng dẫn mới nhất của chúng tôi.

Trí tuệ nhân tạo

Giải thích về ảo giác AI: Tại sao các mô hình ngôn ngữ lại tạo nên mọi thứ và cách giảm thiểu nó

Ảo giác AI đã giải thích: chúng là gì, tại sao mô hình ngôn ngữ tạo ra chúng, các loại phổ biến, cách giảm thiểu chúng bằng cách căn cứ và nhắc nhở …

Đọc bài viết →
DevOps

Giải thích về các biến môi trường: Tệp .env, bí mật và cấu hình được thực hiện đúng

Các biến môi trường được giải thích bằng các ví dụ Python mà chúng tôi đã chạy: đọc và thiết lập chúng, tại sao mọi giá trị đều là một chuỗi, tệp .e…

Đọc bài viết →
Phát triển phần mềm

Giải thích về giới hạn tỷ lệ API: Thuật toán, tiêu đề và xử lý lỗi 429

Giới hạn tốc độ API được giải thích bằng mô phỏng mà chúng tôi đã chạy: nhóm mã thông báo, cửa sổ cố định, cửa sổ trượt, 429 phản hồi, tiêu đề giới …

Đọc bài viết →
Tự động hóa kiểm thử

Chế giễu bằng Python: unittest.mock, patch và những sai lầm khiến bài kiểm tra nói dối

Mô phỏng bằng Python với unittest.mock, đã được thử nghiệm: Mock và return_value, side_effect, vá lỗi nơi sử dụng tên, thông số kỹ thuật và thông số…

Đọc bài viết →
Kiểm thử phần mềm

Giải thích về phạm vi bảo hiểm của mã: Phạm vi tuyến so với chi nhánh và ý nghĩa thực sự 100%

Phạm vi bảo hiểm mã được giải thích bằng cách chạy phạm vi bảo hiểm thực tế: phạm vi bảo hiểm dòng, chi nhánh và điều kiện, đọc báo cáo, lý do tại s…

Đọc bài viết →
Cơ sở dữ liệu & SQL

DELETE vs TRUNCATE vs DROP trong SQL: Sự khác biệt, khôi phục và thời điểm sử dụng mỗi loại

DELETE vs TRUNCATE vs DROP được giải thích bằng SQL đã được thử nghiệm: mỗi loại loại bỏ, khôi phục, kích hoạt, đặt lại danh tính, tốc độ và Postgre…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích về Chế độ xem SQL: Tạo, sử dụng và tránh những cạm bẫy, kèm theo ví dụ

Chế độ xem SQL được giải thích bằng các truy vấn chúng tôi đã chạy: tạo chế độ xem, kết quả trực tiếp, ẩn cột, hiệu suất, chế độ xem có thể cập nhật…

Đọc bài viết →
Phát triển phần mềm

Giao diện TypeScript so với loại: Sự khác biệt thực sự, được thử nghiệm bằng trình biên dịch

Giao diện TypeScript so với loại, được kiểm tra bằng trình biên dịch thực: cả hai có thể làm gì, chỉ một người có thể làm gì, hợp nhất khai báo, mở …

Đọc bài viết →
Phát triển phần mềm

Giải thích về Python *args và **kwargs: Hàm linh hoạt với ví dụ rõ ràng

Python *args và **kwargs được giải thích bằng mã chúng tôi đã chạy: đóng gói và giải nén, thứ tự tham số, đối số chỉ từ khóa và chỉ vị trí, trình tr…

Đọc bài viết →
Phát triển phần mềm

Hàm Lambda của Python: Cú pháp, cách sử dụng thực tế và khi nào không nên sử dụng chúng

Các hàm lambda của Python được giải thích bằng mã chúng tôi đã chạy: cú pháp, sắp xếp bằng khóa, bản đồ và bộ lọc, các phần đóng, bẫy liên kết muộn …

Đọc bài viết →
Trí tuệ nhân tạo

Đại lý AI là gì? Cách chúng hoạt động, với vòng lặp tác nhân đơn giản, bạn có thể chạy

Tác nhân AI là gì? Hướng dẫn đơn giản về vòng lặp tác nhân, công cụ, bộ nhớ và lan can, với một vòng lặp Python nhỏ mà chúng tôi đã chạy, những rủi …

Đọc bài viết →
DevOps

Giám sát và Khả năng quan sát: Sự khác biệt thực sự, với nhật ký, số liệu và dấu vết

Giải thích về giám sát và khả năng quan sát: lỗi đã biết và chưa biết, nhật ký, số liệu và dấu vết, hướng dẫn về sự cố thanh toán, tín hiệu vàng, Op…

Đọc bài viết →
DevOps

Docker Volumes vs Bind Mounts: Duy trì dữ liệu vùng chứa đúng cách

Giải thích về khối lượng Docker và liên kết gắn kết: tại sao dữ liệu vùng chứa biến mất, khối lượng được đặt tên, liên kết gắn kết, tmpfs, ví dụ về …

Đọc bài viết →
Tự động hóa kiểm thử

TDD vs BDD: Key Differences, One Feature Built Both Ways and When to Use Each

TDD và BDD được giải thích bằng một tính năng giảm giá được xây dựng theo cả hai cách: tái cấu trúc màu đỏ-xanh với mã chúng tôi đã chạy, kịch bản C…

Đọc bài viết →
Kiểm thử phần mềm

Kiểm tra chấp nhận của người dùng (UAT): Quy trình, danh sách kiểm tra và ví dụ thực tế

Giải thích về thử nghiệm chấp nhận của người dùng: ai chạy nó, nó khác với QA như thế nào, quy trình bảy bước, mẫu trường hợp thử nghiệm UAT, danh s…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích về các giá trị NULL của SQL: IS NULL, COALESCE, NULLIF và những cái bẫy cần tránh

Các giá trị SQL NULL được giải thích bằng các truy vấn chúng tôi đã chạy: logic ba giá trị, IS NULL, COALESCE, NULLIF, cách tổng hợp, kết hợp và sắp…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Câu lệnh SQL CASE WHEN: Cú pháp, ví dụ thực tế và các lỗi thường gặp

TRƯỜNG HỢP SQL KHI được giải thích bằng các truy vấn mà chúng tôi đã chạy: các biểu mẫu đơn giản và được tìm kiếm, thứ tự điều kiện, các thủ thuật S…

Đọc bài viết →
Phát triển phần mềm

JWT là gì? Mã thông báo Web JSON được giải thích bằng một ví dụ hoạt động

JWT là gì? Mã thông báo Web JSON đã giải thích: ba phần, mã thông báo được xây dựng và giả mạo trong mã chúng tôi đã chạy, JWT so với phiên, lưu trữ…

Đọc bài viết →
Phát triển phần mềm

Giải thích về vòng lặp sự kiện JavaScript: Ngăn xếp cuộc gọi, Microtask và bộ hẹn giờ kèm ví dụ

Vòng lặp sự kiện JavaScript được giải thích bằng mã chúng tôi đã chạy: ngăn xếp cuộc gọi, hàng đợi tác vụ và vi nhiệm, tại sao setTimeout 0 không di…

Đọc bài viết →
Phát triển phần mềm

Giải thích về trình tạo và năng suất của Python: Tiết kiệm bộ nhớ bằng các ví dụ thực tế

Trình tạo và lợi nhuận Python được giải thích bằng mã chúng tôi đã chạy: cách chúng tạm dừng và tiếp tục, đo mức tiết kiệm bộ nhớ, quy trình, chuỗi …

Đọc bài viết →
Trí tuệ nhân tạo

Nhúng là gì? Giải thích sự tương đồng về vectơ và Cosine một cách đơn giản

nhúng là gì? Hướng dẫn bằng ngôn ngữ đơn giản về vectơ, độ tương tự cosine và tìm kiếm ngữ nghĩa, với một ví dụ nhỏ mà chúng tôi đã chạy, các cách s…

Đọc bài viết →
DevOps

Triển khai Blue-Green và Canary: Sự khác biệt, sự đánh đổi và cách lựa chọn

Giải thích về triển khai Blue-green và Canary: cách hoạt động của từng loại, chi phí, rủi ro và khôi phục, nhóm người dùng ổn định mà chúng tôi đã t…

Đọc bài viết →
Tự động hóa kiểm thử

Kiểm tra không ổn định: Nguyên nhân gây ra chúng và cách khắc phục chúng vĩnh viễn

Các thử nghiệm không ổn định được giải thích bằng các bản demo mà chúng tôi đã chạy: nguyên nhân chính, cách xác nhận và chẩn đoán nguyên nhân, cách…

Đọc bài viết →
Kiểm thử phần mềm

Kiểm tra tải và kiểm tra căng thẳng: Sự khác biệt, số liệu và ví dụ về k6

Giải thích về thử nghiệm tải và thử nghiệm căng thẳng: mỗi thử nghiệm chứng minh điều gì, thử nghiệm tăng đột biến và ngâm, số liệu quan trọng, lý d…

Đọc bài viết →
Kiểm thử phần mềm

Trường hợp thử nghiệm và kịch bản thử nghiệm: Sự khác biệt chính, ví dụ và thời điểm sử dụng từng trường hợp

Giải thích trường hợp kiểm thử và kịch bản kiểm thử: định nghĩa rõ ràng, bảng cạnh nhau, một tính năng đặt lại mật khẩu được lấy từ các tình huống n…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Tối ưu hóa truy vấn SQL: Đọc kế hoạch thực thi và sửa các truy vấn chậm, có tính thời gian

Đã thử nghiệm tối ưu hóa truy vấn SQL trên một triệu hàng: đọc kế hoạch thực hiện, thêm chỉ mục phù hợp, sửa các bộ lọc không thể mở rộng, sử dụng c…

Đọc bài viết →
Cơ sở dữ liệu & SQL

SQL UNION và UNION ALL: Sự khác biệt, ví dụ và hiệu suất đã được kiểm tra

SQL UNION và UNION ALL được giải thích bằng các truy vấn chúng tôi đã chạy: trùng lặp, cả hai quy tắc đều tuân theo, lỗi dữ liệu thực, hiệu suất đượ…

Đọc bài viết →
Phát triển phần mềm

Hướng dẫn API tìm nạp JavaScript: GET, POST, Xử lý lỗi và hết thời gian chờ

Hướng dẫn API tìm nạp JavaScript đã được thử nghiệm trên máy chủ cục bộ: GET và POST, tại sao 404 không gửi, trình trợ giúp có thể sử dụng lại, chuỗ…

Đọc bài viết →
Phát triển phần mềm

Xử lý tệp Python: Đọc, ghi, CSV, JSON và pathlib kèm ví dụ

Việc xử lý tệp Python được giải thích bằng mã chúng tôi đã chạy: chế độ mở, với, đọc tệp lớn, CSV, JSON, pathlib, tệp nhị phân, ghi an toàn, xử lý l…

Đọc bài viết →
Phát triển phần mềm

Các lớp và đối tượng Python: Hướng dẫn OOP với các ví dụ thực tế

Các lớp và đối tượng Python được giải thích bằng mã mà chúng tôi đã chạy: __init__, các phương thức, thuộc tính lớp và phiên bản, tính kế thừa, thuộ…

Đọc bài viết →
Trí tuệ nhân tạo

Mô hình ngôn ngữ lớn là gì? LLM hoạt động như thế nào, được giải thích mà không cường điệu hóa

Mô hình ngôn ngữ lớn là gì? LLM được giải thích bằng ngôn ngữ đơn giản: mã thông báo, phần nhúng, sự chú ý, đào tạo, cửa sổ nhiệt độ và ngữ cảnh, mộ…

Đọc bài viết →
DevOps

Các lệnh Linux cho người mới bắt đầu: Hướng dẫn thiết bị đầu cuối cần thiết kèm ví dụ

Các lệnh Linux dành cho người mới bắt đầu, được nhóm theo tác vụ: điều hướng, tệp, xem nhật ký, grep, đường dẫn, quyền, quy trình và lưu trữ, cùng v…

Đọc bài viết →
Tự động hóa kiểm thử

Selenium vs Nhà viết kịch: Sự khác biệt chính, So sánh mã và nên chọn cái nào

Selenium và Playwright được so sánh: kiến trúc, chờ đợi, hỗ trợ trình duyệt và ngôn ngữ, gỡ lỗi, kiểm tra giống nhau ở cả hai công cụ, lời khuyên di…

Đọc bài viết →
Kiểm thử phần mềm

Phân vùng tương đương: Giải thích kỹ thuật thiết kế thử nghiệm bằng các ví dụ đã thực hiện

Giải thích về phân vùng tương đương: cách tìm các phân vùng hợp lệ và không hợp lệ, các ví dụ hoạt động theo độ tuổi, mật khẩu và phiếu giảm giá, cá…

Đọc bài viết →
Kiểm thử phần mềm

Mức độ nghiêm trọng và mức độ ưu tiên trong kiểm thử phần mềm: Sự khác biệt, Ma trận và ví dụ thực tế

Giải thích về mức độ nghiêm trọng và mức độ ưu tiên trong kiểm thử phần mềm: định nghĩa rõ ràng, ma trận bốn chiều với các ví dụ, thang đo cấp độ, a…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Hướng dẫn về truy vấn con SQL: Các loại, truy vấn con tương quan và TỒN TẠI kèm ví dụ

Hướng dẫn về truy vấn con SQL với các truy vấn chúng tôi đã chạy: truy vấn con vô hướng, IN, FROM và SELECT, truy vấn con tương quan, EXISTS, bẫy và…

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích về giao dịch SQL và ACID: Các mức CAM KẾT, ROLLBACK và Cô lập

Các giao dịch SQL và ACID được giải thích bằng chuyển khoản ngân hàng mà chúng tôi đã thực hiện: CAM KẾT, ROLLBACK, điểm lưu trữ, khóa, mức cách ly,…

Đọc bài viết →
Phát triển phần mềm

Bảng cheat lệnh Git: Các lệnh bạn thực sự sử dụng, kèm theo ví dụ

Một bảng ghi lệnh Git được nhóm theo nhiệm vụ: thiết lập, dàn dựng, nhánh, điều khiển từ xa, lưu trữ, lịch sử và hoàn tác các lỗi, với đầu ra từ kho…

Đọc bài viết →
Phát triển phần mềm

Giải thích về các lời hứa trong JavaScript: then, Catch, Promise.all và các lỗi thường gặp

Lời hứa JavaScript được giải thích bằng mã chúng tôi đã chạy: trạng thái, then và chuỗi bắt, xử lý lỗi, Promise.all, allSettled, chủng tộc và bất kỳ…

Đọc bài viết →
Phát triển phần mềm

Hướng dẫn từ điển Python: Phương thức, ví dụ và mẫu chung

Hướng dẫn từ điển Python với mã chúng tôi đã chạy: tạo, đọc và cập nhật các ký tự, các phương thức chính, hợp nhất, hiểu, đếm và nhóm các mẫu cũng n…

Đọc bài viết →
Trí tuệ nhân tạo

RAG là gì? Giải thích về thế hệ tăng cường truy xuất bằng một ví dụ hoạt động

RAG là gì? Thế hệ tăng cường truy xuất được giải thích từng bước: lập chỉ mục, phân nhóm, nhúng, truy xuất, một ví dụ Python hoạt động nhỏ, đánh giá…

Đọc bài viết →
DevOps

Hướng dẫn về Terraform cho người mới bắt đầu: Cơ sở hạ tầng dưới dạng mã từ tệp đầu tiên đến mô-đun

Hướng dẫn về Terraform dành cho người mới bắt đầu: bắt đầu không cần tài khoản đám mây, tìm hiểu về init, lập kế hoạch và áp dụng, sau đó là các biế…

Đọc bài viết →
DevOps

Docker vs Kubernetes: Key Differences, How They Work Together and Which You Need

Docker vs Kubernetes giải thích: mỗi cái làm gì, cùng một ứng dụng chạy với cả hai, so sánh Docker Compose và Swarm, sự thay đổi của dockershim và c…

Đọc bài viết →
Tự động hóa kiểm thử

Hướng dẫn Pytest cho người mới bắt đầu: Đồ đạc, tham số hóa và ví dụ thực tế

Hướng dẫn về pytest dành cho người mới bắt đầu với các bài kiểm tra chúng tôi đã chạy trên pytest 9.2: xác nhận, đồ đạc, tham số, conftest, điểm đán…

Đọc bài viết →
Kiểm thử phần mềm

Vòng đời kiểm thử phần mềm (STLC): 6 giai đoạn, tiêu chí đầu vào và đầu ra, ví dụ

Vòng đời kiểm thử phần mềm giải thích: sáu giai đoạn STLC với tiêu chí đầu vào và đầu ra, sản phẩm phân phối, ví dụ về tính năng đăng nhập hoạt động…

Đọc bài viết →
Phát triển phần mềm

Git merge vs rebase: khác biệt, ví dụ và khi nào dùng cái nào

Git merge vs rebase được giải thích bằng đầu ra log thực tế, bảng so sánh, quy tắc vàng của rebase và quy trình làm việc nhóm an toàn.

Đọc bài viết →
Phát triển phần mềm

List comprehension trong Python: cú pháp, ví dụ và khi nào nên tránh

List comprehension trong Python: cú pháp, lọc dữ liệu, if-else, vòng lặp lồng nhau, thời gian đo thực tế và khi nào vòng lặp for thông thường tốt hơn.

Đọc bài viết →
Cơ sở dữ liệu & SQL

Giải thích SQL JOIN kèm ví dụ (Inner, Left, Right, Full)

Hiểu SQL JOIN từng bước với bảng và truy vấn mẫu: INNER, LEFT, RIGHT, FULL, CROSS và SELF, cùng lỗi thường gặp và mẹo hiệu năng.

Đọc bài viết →