JavaScript 中的 Promise 类
在本文中,我们解释了 JavaScript 中的 Promise 类。
YouTube Video
Promise
Promise 类用于处理异步操作。它处理操作成功时的结果或发生失败时的错误处理。传统上,回调函数被用来等待异步操作完成,但 Promise 使这一过程变得更加清晰和强大。
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));- 此代码是一个异步处理的示例,在一秒后显示“完成!”。
- 首先,使用
new Promise创建一个新的Promise对象。参数是一个带有两个回调函数的函数:resolve表示成功,reject表示失败。 - 使用
setTimeout在一秒后调用resolve()。 promise对象的then()方法等待完成并显示结果。
- 首先,使用
基本结构
Promise 是一个最终会产生成功或失败结果的对象。
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});- 成功时,调用
resolve()。 - 失败时,调用
reject()。
Promise 对象有三种状态。
1promise
2 .then((result) => {
3 console.log(result);
4 })
5 .catch((error) => {
6 console.error(error);
7 })- 进行中
- 异步处理尚未完成。
- 已完成
- 异步处理成功,结果由
resolve()返回。使用then()方法接收结果。
- 异步处理成功,结果由
- 已拒绝
- 异步处理失败,通过
reject()触发错误。使用catch()方法接收错误。
- 异步处理失败,通过
then() 和 catch() 方法
通过使用 Promise,可以定义异步操作完成时要执行的操作。为此,可以使用 then() 和 catch() 方法。
then()
1const promise = new Promise((resolve, reject) => {
2 resolve('Operation successful!');
3});
4
5promise.then((result) => {
6 console.log(result); // "Operation successful!"
7});then()方法指定了Promise成功时要调用的函数。
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});catch()方法指定了Promise失败时要调用的函数。
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 });finally()方法定义了无论Promise是成功还是失败,都会在最后执行的代码。
“then()” 链
then() 会返回一个新的 Promise,因此你可以链式调用下一个 then()。
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 });- 在此代码中,最初的
resolve()传递值 1,每个then返回的值都会传递给下一个then。 - 使用
catch(),你可以在一个地方处理链中发生的所有错误。
实际示例
例如,Promises通常用于从服务器获取数据。让我们来看一个使用fetch() API的示例。
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 });- 在此代码中,由于
fetch()返回一个Promise,因此使用then()在收到服务器响应后处理数据。使用catch()来处理错误。
处理多个Promise
Promise.all()
要同时执行多个Promises,并仅在全部成功时继续,请使用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 });- 仅当所有
Promises都成功时才调用then()。如果有一个失败,则调用catch()。
Promise.allSettled()
如果你想同时运行多个 Promise 并且无论成功或失败都获取所有结果,请使用 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 });- 一旦所有的
Promise都已完成(无论是已实现还是已拒绝),就会调用then()。每个结果都包含一个status属性('fulfilled' 或 'rejected')。即使有一些失败,也不会影响其他操作。
Promise.race()
Promise.race() 返回最先完成(无论成功还是失败)的 Promise 的结果。
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});- 如同此例,会返回第一个完成的
Promise的结果。
与async/await的关系
使用async/await语法可以更直观地书写Promises。async函数始终返回一个Promise,而await等待该Promise解决。
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();通过这种方式使用async/await,可以像编写同步代码一样书写异步操作,使其更易于阅读。
总结
Promise是一个用于处理异步操作成败的对象。- 使用
then()处理成功的操作,使用catch()处理错误。 finally()定义了无论成功还是失败最终都会执行的代码。- 可以使用
Promise.all()或Promise.race()一起处理多个Promise。 async/await是更简单书写Promise的语法。
您可以在我们的YouTube频道上使用Visual Studio Code跟随上述文章进行学习。 请也查看我们的YouTube频道。