第2课_ES6 Promise基础
热度🔥:56 免费课程
授课语音
了解如何运用ES6 Promise进行异步编程
在传统的JavaScript中,异步编程常常依赖回调函数,这可能导致“回调地狱”问题,代码可读性差且难以维护。ES6引入了Promise
,它提供了一种更加优雅的方式来处理异步操作。通过Promise
,我们可以更好地控制异步操作的流程和错误处理,提高代码的可读性和可维护性。
1. Promise概述
Promise
是一个表示异步操作最终完成或失败的对象,它可以让我们以同步的方式书写异步代码。Promise
有三种状态:
- Pending(待定): 初始状态,异步操作尚未完成。
- Fulfilled(已完成): 异步操作完成,结果已返回。
- Rejected(已拒绝): 异步操作失败,返回错误。
2. 创建一个Promise
我们可以使用new Promise()
来创建一个Promise
对象,构造函数接受一个执行器函数(executor),该函数有两个参数:resolve
和reject
。当异步操作成功时,调用resolve
;当异步操作失败时,调用reject
。
const myPromise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve('操作成功');
} else {
reject('操作失败');
}
});
myPromise.then(result => {
console.log(result); // 输出:操作成功
}).catch(error => {
console.log(error); // 输出:操作失败
});
解释:
resolve('操作成功')
:表示异步操作成功,Promise
进入已完成状态。reject('操作失败')
:表示异步操作失败,Promise
进入已拒绝状态。then()
方法:处理Promise
成功的情况。catch()
方法:处理Promise
失败的情况。
3. Promise的状态变化
Promise
的状态只能从Pending
转为Fulfilled
或Rejected
,一旦状态改变,就无法再次改变。这种状态机的设计确保了异步操作的唯一性和不可变性。
3.1 then()方法
then()
方法用于处理Promise
成功的结果,它返回一个新的Promise
对象,可以链式调用。
const myPromise = new Promise((resolve, reject) => {
resolve('操作成功');
});
myPromise
.then(result => {
console.log(result); // 输出:操作成功
return '新的结果';
})
.then(newResult => {
console.log(newResult); // 输出:新的结果
})
.catch(error => {
console.log(error);
});
解释:
- 每次调用
then()
时,返回一个新的Promise
,可以继续链式调用。 then()
方法中的返回值会被下一个then()
捕获。
3.2 catch()方法
catch()
方法用于捕获Promise
中的错误,它是then()
的错误处理机制。catch()
可以链式调用,用来处理异步操作中可能发生的任何错误。
const myPromise = new Promise((resolve, reject) => {
reject('操作失败');
});
myPromise
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error); // 输出:操作失败
});
解释:
catch()
方法捕获Promise
中的reject
状态,输出错误信息。
4. Promise.all()和Promise.race()
ES6还提供了两个非常实用的静态方法:Promise.all()
和Promise.race()
,它们用于处理多个Promise
。
4.1 Promise.all()
Promise.all()
方法用于接收一个Promise
数组,当所有Promise
都成功时,它会返回一个新的Promise
,其值是每个Promise
的结果。如果其中一个Promise
失败,Promise.all()
会立即失败。
const promise1 = new Promise((resolve, reject) => resolve('第一个任务完成'));
const promise2 = new Promise((resolve, reject) => resolve('第二个任务完成'));
Promise.all([promise1, promise2])
.then(results => {
console.log(results); // 输出:['第一个任务完成', '第二个任务完成']
})
.catch(error => {
console.log(error);
});
解释:
Promise.all()
等待所有Promise
都完成后,再执行then()
,并返回每个Promise
的结果数组。
4.2 Promise.race()
Promise.race()
方法用于接收一个Promise
数组,返回一个新的Promise
,它会根据第一个完成的Promise
的结果来决定。
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 1000, '第一个任务完成'));
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 500, '第二个任务完成'));
Promise.race([promise1, promise2])
.then(result => {
console.log(result); // 输出:第二个任务完成
})
.catch(error => {
console.log(error);
});
解释:
Promise.race()
返回第一个完成的Promise
的结果,不论它是成功还是失败。
5. Promise链式调用与错误处理
链式调用使得我们可以依次处理多个异步操作,同时保持代码的清晰性。每个then()
返回的Promise
都可以传递结果或错误,最终通过catch()
进行错误捕获。
const myPromise = new Promise((resolve, reject) => {
resolve('任务1完成');
});
myPromise
.then(result => {
console.log(result); // 输出:任务1完成
return '任务2完成';
})
.then(result => {
console.log(result); // 输出:任务2完成
throw new Error('任务3出错');
})
.catch(error => {
console.log(error.message); // 输出:任务3出错
});
解释:
- 通过
then()
方法链式调用多个异步操作,每个then()
返回的Promise
都会传递结果。 - 如果在某个
then()
中抛出错误,错误会被后续的catch()
捕获。
6. 总结
Promise
使得异步编程更加直观,避免了回调函数的嵌套。- 通过
then()
和catch()
可以处理异步操作的成功和失败。 Promise.all()
和Promise.race()
可以同时处理多个异步操作。Promise
的链式调用使得异步操作的代码更加清晰,并且能够更好地捕获错误。
通过掌握Promise
,你可以更高效地编写异步代码,减少代码中的嵌套和复杂性,提升代码的可维护性。