Bởi vì, theo đặc điểm kỹ thuật, hứa hẹn sẽ gọi trình xử lý giải quyết của họ SAU khi luồng hiện tại thực hiện bung ra và kết thúc lại thành "mã nền tảng". Điều đó đảm bảo rằng chúng luôn được gọi là không đồng bộ.
Vì vậy, do đó bạn nhìn thấy console.log('b')
trước tiên khi chuỗi đó thực hiện kết thúc và sau đó trình xử lý giải quyết được gọi là nơi bạn xem console.log('a')
.
Từ Promises/A+ specification:
2.2.4 onFulfilled hoặc onRejected phải không được gọi cho đến khi thực hiện bối cảnh chồng chỉ chứa mã nền tảng. [3.1].
Và, đây là lưu ý [3.1]:
Here “nền tảng mã” nghĩa là công cụ, môi trường, và hứa mã thực hiện. Trong thực tế, yêu cầu này đảm bảo rằng onFulfilled và onRejected thực hiện không đồng bộ, sau sự kiện vòng lặp trong đó được gọi, và với một ngăn xếp mới. Đây có thể là được triển khai bằng cơ chế “tác vụ macro” như setTimeout hoặc setImmediate hoặc với cơ chế “vi nhiệm vụ” chẳng hạn như MutationObserver hoặc process.nextTick. Kể từ khi triển khai lời hứa được coi là mã nền tảng, bản thân nó có thể chứa một xếp hàng nhiệm vụ hàng đợi hoặc “tấm bạt lò xo” trong đó các trình xử lý được gọi.
này được thực hiện để cung cấp phù hợp để thực hiện vì vậy không có vấn đề khi sự hứa hẹn được giải quyết (đồng bộ hoặc không đồng bộ), các then()
xử lý luôn luôn được gọi trong thời gian tương tự so với các mã khác. Vì nhiều lời hứa được giải quyết không đồng bộ, cách duy nhất để thực hiện một lời hứa nhất quán bất kể nó được giải quyết như thế nào là làm cho chúng luôn gọi trình xử lý .then()
của chúng không đồng bộ.