Definition
Promise là một lớp đối tượng được giới thiệu ở ES6 giúp xử lý các tác vụ bất đồng bộ. Bắt chúng phải “cam kết một lời hứa” nào đó, đảm bảo các tác vụ bất đồng bộ phải trả về giá trị hoặc trả về lỗi.
An Analogy
Giả sử nhà Alice có một cái giếng. Ông của Alice giao cho cô nhiệm vụ là múc nước lên để tưới cây.
Nếu Alice múc nước lên thành công, nước có ở trong xô, ông của Aclic sẽ đem đi tưới cây. Tuy nhiên, nếu vì bất kỳ lý do nào đó (chẳng hạn như xô bị lủng, dây thừng kéo xô bị đứt, …) làm cho việc múc nước không thành công, ông của Alice sẽ không có nước để tưới cây.
Trong khi Alice múc nước, ông của Alice có thể sẽ làm những công việc khác như rải hạt giống, xới đất, …
Chúng ta có thể xem như nhiệm vụ mà ông của Alice giao cho Alice là một lời hứa. Việc múc nước lên là một tác vụ bất đồng bộ, bởi vì trong khi Alice múc nước thì ông của Alice có thể làm những việc khác.
Promise States
Một promise sẽ có các trạng thái sau:
pending: trạng thái khởi tạo, chưa bịfulfilledhayrejected.fulfilled: thể hiện rằng tác vụ đã được thực thi thành công.rejected: tác vụ thực thi thất bại.

Các trạng thái này không thể được truy cập hay chỉnh sửa theo một cách thông thường mà chỉ có thể thông qua các hàm cho trước, cụ thể là resolve và reject.
Với ví dụ ở trên, nếu việc múc nước thành công, lời hứa của Alice đối với ông sẽ có trạng thái là fulfilled. Ngược lại, lời hứa sẽ có trạng thái là rejected. Khi Alice bắt đầu múc nước thì lời hứa của Alice sẽ có trạng thái là pending.
Construction
Khởi tạo đối tượng promise bằng constructor của lớp đối tượng Promise và truyền vào một callback có tên là executor, gồm hai tham số cũng là các callback:
resolve: thực thi để chuyển promise sang trạng tháifulfilled.reject: thực thi để chuyển promise sang trạng tháirejected.
Khởi tạo đối tượng cho lời hứa của Alice:
const getWaterPromise = new Promise(function (resolve, reject) {
// Do something and either resolve or reject
})Executor
Executor sẽ được gọi trước cả khi đối tượng promise được tạo. Executor là nơi diễn ra các tác vụ bất đồng bộ và giúp đảm bảo các tác vụ đó phải trả về giá trị hoặc lỗi.
Ta gọi các đoạn code bất đồng bộ mà sản sinh ra giá trị hoặc lỗi là producing code. Còn các đoạn code sử dụng giá trị hoặc lỗi của producing code thì được gọi là consuming code.
Trong trường hợp Alice múc nước lên thành công, hàm executor sẽ cần phải gọi hàm resolve để trả về kết quả:
const getWaterPromise = new Promise(function (resolve, reject) {
// Got the water
let value = "water"
resolve(value) // An assurance of getting the water successfully
})Trường hợp ngược lại, executor sẽ cần phải gọi hàm reject để trả về lỗi:
const getWaterPromise = new Promise(function (resolve, reject) {
// Oops, the bucket has a hole.
reject(new Error("Failed")) // Throwing an error
})Memory leak
Bắt buộc gọi một trong hai callback
resolvevàrejecttrong executor. Nếu không, đối tượng promise sẽ có trạng thái là pending. Trạng thái này gây rò rỉ bộ nhớ khi không chuyển sang hai trạng thái còn lại.
Nếu một trong hai callback resolve và reject đã được thực thi thì promise sẽ không thực thi resolve hay reject nữa:
const getWaterPromise = new Promise(function (resolve, reject) {
resolve("I am surely going to get resolved!")
reject(new Error("Will this be ignored?")) // ignored
resolve("Ignored?") // ignored
})Giả sử chúng ta muốn tạo ra một promise mà trạng thái ban đầu của nó đã là fulfilled hoặc rejected. Ta có thể làm như sau:
const fulfilledPromise = new Promise((resolve) => resolve())
const rejectedPromise = new Promise((resolve, reject) => reject())Promise Results
Xét executor của promise trong cả hai trường hợp:
function(resolve, reject) {
// Got the water
let value = 'water'
resolve(value) // An assurance of getting the water successfully
}
function(resolve, reject) {
// Oops, the bucket has a hole.
reject(new Error("can't get water")) // Throwing an error
}Có thể thấy, resolve và reject đều nhận đối số đầu vào. Các đối số này sẽ được chuyển cho các handler methods.
Consumer function trong ví dụ của nhà Alice sẽ là waterPlants. Bên trong waterPlants sẽ gọi sử dụng các handler methods của promise như sau:
const waterPlants = () => {
getWaterPromise
.then((result) => console.log(`Watering the plants with ${result}`)) // Watering the plants with water
.catch((error) => console.log(`Can't water the plants. ${error}`)) // Can't water the plants. Error: can't get water
.finally(() => console.log("Promise is executed"))
}