JavaScript - Chuyện gì xảy ra khi 1 Promise không bao giờ được resolve

Đi từ Event loop

Từ định nghĩa của resolve method - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve, ta hiểu đơn giản là việc call resolve() sẽ call xử lý nằm trong method then() hoặc sau await.

Ví dụ với đoạn code sau sẽ minh họa điều đó:

const promise = new Promise((resolve) => {
  console.log("start");
  if (true) resolve();
});

promise.then(() => console.log("done."));

Để hiểu rõ thì ta dùng https://www.jsv9000.app/ để xem Event Loop trong JS hoạt động thế nào.

Bước đầu tiên là "Evaluate Script" - chạy code theo cách đồng bộ - Synchronously.

Bấm next sẽ tới bước tiếp theo. Trong Call Stack đã có 1 anonymous function đó là: (resolve) => { console.log("start"); if (true) resolve(); }.

Tiếp theo message "start" được hiển thị.

Tiếp theo, Microtask Queue có thêm 1 anonymous function, đó chính là () => console.log("done.").

Tiếp thep, do resolve(); được call nên Microtasks tương ứng được thực hiện nên được đưa vào Call Stack.

Và function trong Call Stack được thực thi và kết quả là "done." message được hiển thị.

Cuối cùng Call Stack trống và kết thúc.

Vậy thì chuyện gì xảy ra khi 1 Promise không bao giờ được resolve?

Ta chạy thử với đoạn code sau:

const promise = new Promise((resolve) => {
  console.log("start");
  if (false) resolve();
});

promise.then(() => console.log("done."));

Trong đó resolve(); sẽ không bao giờ được thực thi.

Tương tự bên trên, chỉ khác là resolve(); không được thực thi nên callback nằm trong then(); không được đưa vào Microtask Queue. Điều đó dẫn đến chương trình thoát sau khi chỉ thực hiện console.log("start"); .

Tương tự với async và await:

const simple = async () => {
  console.log("start");
  // resolve(); không bao giờ được call
  await new Promise((resolve) => {});
  console.log("done.");
};
simple();

Tóm lại, callback dành cho promise đó không được thực thi và thoát luôn.

Reference