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
Promisemớ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:resolvecho thành công vàrejectcho 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 khiPromisethà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 khiPromisethấ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ểPromisethà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ộtthensẽ được truyền sangthentiế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ácPromisethà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
Promiselà 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
Promisecùng nhau bằng cách sử dụngPromise.all()hoặcPromise.race(). async/awaitlà cú pháp để viếtPromisemộ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.