2.1 Tạo promises
Promises là đối tượng đại diện cho việc hoàn thành (hoặc thất bại) của một hoạt động bất đồng bộ và kết quả của nó. Chúng được giới thiệu trong ES6 (ECMAScript 2015) và trở thành cách chuẩn để làm việc với mã bất đồng bộ trong JavaScript.
Các khái niệm chính
Promise có thể ở một trong ba trạng thái:
- Pending (đang chờ): trạng thái ban đầu, chưa hoàn thành và chưa bị từ chối.
- Fulfilled (đã hoàn thành): hoạt động đã hoàn thành thành công.
- Rejected (bị từ chối): hoạt động đã kết thúc với lỗi.
Tạo promise
Promise được tạo bằng cách sử dụng hàm khởi tạo Promise
, hàm này chấp nhận một hàm thực thi
(executor function). Hàm này chấp nhận hai đối số: resolve
và reject
.
Bên trong hàm này, mã bất đồng bộ được thực hiện, và trong trường hợp thành công, resolve
được gọi,
còn trong trường hợp lỗi — reject
.
Cú pháp:
const promise = new Promise((resolve, reject) => {
// Hoạt động bất đồng bộ
if (/* hoàn thành thành công */) {
resolve(value); // Thành công
} else {
reject(error); // Lỗi
}
});
Ví dụ tạo promise:
const myPromise = new Promise((resolve, reject) => {
const success = true; // Điều kiện để hoàn thành thành công
if (success) {
resolve('Operation was successful');
} else {
reject('Operation failed');
}
});
2.2 Sử dụng promises
Phương thức then
Phương thức then
được sử dụng để xử lý thành công của promise. Nó nhận hai hàm: đầu tiên để xử lý
thành công và thứ hai để xử lý lỗi. Tuy nhiên, thường để xử lý lỗi, phương thức catch
được sử dụng.
Ví dụ sử dụng then:
myPromise.then(
(successMessage) => {
console.log(successMessage); // Sẽ in ra: Operation was successful
},
(errorMessage) => {
console.error(errorMessage); // Sẽ được gọi trong trường hợp lỗi
}
);
Phương thức catch
Phương thức catch
được sử dụng để xử lý lỗi của promise. Nó nhận một hàm, hàm này sẽ được gọi
trong trường hợp promise bị từ chối.
Ví dụ sử dụng catch:
myPromise
.then((successMessage) => {
console.log(successMessage);
})
.catch((errorMessage) => {
console.error(errorMessage); // Sẽ được gọi: Operation failed
});
Phương thức finally
Phương thức finally
được sử dụng để thực thi mã bất kể kết quả của promise (thành công hay lỗi).
Nó không nhận đối số và được thực thi trong mọi trường hợp sau khi promise được hoàn thành hoặc bị từ chối.
Ví dụ sử dụng finally:
myPromise
.then((successMessage) => {
console.log(successMessage);
})
.catch((errorMessage) => {
console.error(errorMessage);
})
.finally(() => {
console.log('Operation completed'); // Sẽ được gọi trong mọi trường hợp
});
2.3 Các ví dụ về sử dụng promises
Ví dụ 1: Hoạt động bất đồng bộ sử dụng promise
Mô phỏng hoạt động bất đồng bộ với bộ đếm thời gian.
function asyncOperation() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.5;
if (success) {
resolve('Async operation was successful');
} else {
reject('Async operation failed');
}
}, 2000);
});
}
asyncOperation()
.then((message) => {
console.log(message);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log('Async operation completed');
});
Ví dụ 2: Thực hiện nối tiếp promises
Mô phỏng các hoạt động bất đồng bộ nối tiếp.
function firstOperation() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('First operation completed');
resolve('First result');
}, 1000);
});
}
function secondOperation(result) {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Second operation completed');
resolve(`Second result, received: ${result}`);
}, 1000);
});
}
firstOperation()
.then((result) => {
return secondOperation(result);
})
.then((finalResult) => {
console.log(finalResult);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log('Both operations completed');
});
Ví dụ 3: Thực hiện song song promises với Promise.all
Mô phỏng các hoạt động bất đồng bộ song song.
function operationOne() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Operation One completed');
resolve('Result One');
}, 1000);
});
}
function operationTwo() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('Operation Two completed');
resolve('Result Two');
}, 1500);
});
}
Promise.all([operationOne(), operationTwo()])
.then((results) => {
console.log('All operations completed');
console.log(results); // Sẽ in ra: ['Result One', 'Result Two']
})
.catch((error) => {
console.error('One of the operations failed', error);
});
GO TO FULL VERSION