Lớp Promise trong JavaScript
Trong bài viết này, chúng tôi giải thích về lớp Promise trong JavaScript.
YouTube Video
Promise
Lớp Promise
là một lớp dùng để xử lý các thao tác bất đồng bộ. Nó xử lý kết quả nếu thao tác thành công hoặc xử lý lỗi nếu thao tác thất bại. Truyền thống trước đây sử dụng các hàm callback khi bạn cần chờ một thao tác bất đồng bộ hoàn thành, nhưng Promise
làm cho việc này rõ ràng hơn và mạnh mẽ hơn.
1const promise = new Promise((resolve, reject) => {
2 setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
- Đoạn mã này là một ví dụ về quá trình bất đồng bộ hiển thị "Đã xong!" sau một giây.
- Đầu tiên, một đối tượng
Promise
mới được tạo ra bằng cách sử dụngnew Promise
. Đối số là một hàm nhận hai hàm gọi lại:resolve
cho thành công vàreject
cho thất bại. setTimeout
được sử dụng để gọiresolve()
sau một giây.- Phương thức
then()
của đối tượngpromise
đợi hoàn thành và hiển thị kết quả.
- Đầu tiên, một đối tượng
Cấu trúc cơ bản
Promise
là một đối tượng mà kết quả cuối cùng sẽ dẫn đến thành công hoặc thất bại.
1const promise = new Promise((resolve, reject) => {
2 // Asynchronous operation
3 // Flag indicating whether the operation was successful
4 const success = true;
5
6 if (success) {
7 resolve('Operation successful!');
8 } else {
9 reject('An error occurred');
10 }
11});
- Trong trường hợp thành công,
resolve()
sẽ được gọi. - Trong trường hợp thất bại,
reject()
sẽ được gọi.
Đối tượng Promise
có ba trạng thái.
1promise
2 .then((result) => {
3 console.log(result);
4 })
5 .catch((error) => {
6 console.error(error);
7 })
- Đang chờ
- Quá trình bất đồng bộ vẫn chưa hoàn thành.
- Đã hoàn thành
- Quá trình bất đồng bộ thành công và kết quả được trả về bởi
resolve()
. Kết quả được nhận bằng cách sử dụng phương thứcthen()
.
- Quá trình bất đồng bộ thành công và kết quả được trả về bởi
- Đã bị từ chối
- Quá trình bất đồng bộ thất bại và lỗi xuất hiện thông qua
reject()
. Lỗi được nhận bằng cách sử dụng phương thứccatch()
.
- Quá trình bất đồng bộ thất bại và lỗi xuất hiện thông qua
Các phương thức then()
và catch()
Khi sử dụng một Promise
, bạn có thể định nghĩa cần làm gì khi một thao tác bất đồng bộ hoàn thành. Để làm điều này, bạn sử dụng các phương thức then()
và catch()
.
then()
1const promise = new Promise((resolve, reject) => {
2 resolve('Operation successful!');
3});
4
5promise.then((result) => {
6 console.log(result); // "Operation successful!"
7});
- Phương thức
then()
định nghĩa một hàm sẽ được gọi khiPromise
thành công.
catch()
1const promise = new Promise((resolve, reject) => {
2 reject('An error occurred');
3});
4
5promise.catch((error) => {
6 console.error(error); // "An error occurred"
7});
- Phương thức
catch()
định nghĩa một hàm sẽ được gọi khiPromise
thất bại.
Phương thức finally()
1const promise = new Promise((resolve, reject) => {
2 resolve('Operation successful!');
3});
4
5promise
6 .then((result) => {
7 console.log(result);
8 })
9 .catch((error) => {
10 console.error(error);
11 })
12 .finally(() => {
13 console.log('The operation has completed');
14 });
- Phương thức
finally()
định nghĩa mã sẽ được thực thi cuối cùng, bất kểPromise
thành công hay thất bại.
Chuỗi then()
then()
trả về một Promise
mới, vì vậy bạn có thể xâu chuỗi then()
tiếp theo.
1const promise = new Promise((resolve, reject) => {
2 setTimeout(() => {
3 resolve(1);
4 }, 1000);
5});
6
7promise
8 .then(result => {
9 console.log(result); // 1
10 return result + 1;
11 })
12 .then(result => {
13 console.log(result); // 2
14 return result + 1;
15 })
16 .then(result => {
17 console.log(result); // 3
18 })
19 .catch(error => {
20 console.error(error.message); // Something went wrong
21 });
- Trong đoạn mã này,
resolve()
ban đầu truyền giá trị 1, và mỗi giá trị được trả về bởi mộtthen
sẽ được truyền sangthen
tiếp theo. - Sử dụng
catch()
, bạn có thể xử lý bất kỳ lỗi nào xảy ra trong chuỗi ở cùng một nơi.
Ví dụ Thực tế
Ví dụ, Promises
thường được sử dụng để lấy dữ liệu từ máy chủ. Hãy xem một ví dụ sử dụng API fetch()
.
1fetch('https://codesparklab.com/json/example.json')
2 .then(response => {
3 if (!response.ok) {
4 throw new Error('Network error');
5 }
6 return response.json();
7 })
8 .then(data => {
9 console.log(data);
10 })
11 .catch(error => {
12 console.error('Error:', error);
13 });
- Trong mã này, vì
fetch()
trả về mộtPromise
, nênthen()
được sử dụng để xử lý dữ liệu sau khi nhận được phản hồi từ máy chủ. Lỗi được xử lý bằng cách sử dụngcatch()
.
Xử lý Nhiều Promise
Promise.all()
Để thực thi nhiều Promise
cùng một lúc và tiếp tục chỉ khi tất cả thành công, hãy sử dụng Promise.all()
.
1const promise1 = Promise.resolve(1);
2const promise2 = Promise.resolve(2);
3const promise3 = Promise.resolve(3);
4
5Promise.all([promise1, promise2, promise3])
6 .then((results) => {
7 console.log(results); // [1, 2, 3]
8 })
9 .catch((error) => {
10 console.error('Error :', error);
11 });
then()
chỉ được gọi khi tất cả cácPromise
thành công.catch()
được gọi khi chỉ cần một cái thất bại.
Promise.allSettled()
Nếu bạn muốn chạy nhiều Promise
đồng thời và nhận tất cả kết quả bất kể thành công hay thất bại, hãy sử dụng Promise.allSettled()
.
1const promise1 = Promise.resolve(1);
2const promise2 = Promise.reject("Failed");
3const promise3 = Promise.resolve(3);
4
5Promise.allSettled([promise1, promise2, promise3])
6 .then((results) => {
7 results.forEach(result => console.log(result));
8 // [
9 // { status: 'fulfilled', value: 1 },
10 // { status: 'rejected', reason: 'Failed' },
11 // { status: 'fulfilled', value: 3 }
12 // ]
13 });
then()
sẽ được gọi khi tất cả cácPromise
đã hoàn tất (dù được thực hiện hay bị từ chối). Mỗi kết quả bao gồm một thuộc tínhstatus
('fulfilled'
hoặc'rejected'
). Ngay cả khi một số bị thất bại, điều đó cũng không ảnh hưởng đến các thao tác khác.
Promise.race()
Promise.race()
trả về kết quả của Promise
được giải quyết đầu tiên, dù là thành công hay thất bại.
1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5 console.log(result); // "First"
6});
- Như trong ví dụ này, kết quả của
Promise
đầu tiên hoàn tất sẽ được trả về.
Mối quan hệ giữa async
/await
Sử dụng cú pháp async
/await
cho phép bạn viết Promises
một cách trực quan hơn. Một hàm async
luôn trả về một Promise
, và await
chờ Promise
được giải quyết.
1async function fetchData() {
2 try {
3 const response = await fetch('https://codesparklab.com/json/example.json');
4 const data = await response.json();
5 console.log(data);
6 } catch (error) {
7 console.error('Error :', error);
8 }
9}
10
11fetchData();
Bằng cách sử dụng async
/await
theo cách này, các thao tác không đồng bộ có thể được viết như mã đồng bộ, làm cho nó dễ đọc hơn.
Tóm tắt
Promise
là một đối tượng để xử lý thành công hoặc thất bại của các thao tác không đồng bộ.- Xử lý các hoạt động thành công bằng
then()
và lỗi bằngcatch()
. finally()
định nghĩa mã sẽ được thực thi ở cuối bất kể thành công hay thất bại.- Bạn có thể xử lý nhiều
Promise
cùng nhau bằng cách sử dụngPromise.all()
hoặcPromise.race()
. async
/await
là cú pháp để viếtPromise
một cách đơn giản hơn.
Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.