目录
1.对Promise的了解
(1)介绍
(2)Promise 的优缺点
2.Promise的基本用法
(1)创建Promise对象
(2)Promise方法then()
(3)Promise方法catch()
(4)Promise方法all()
(4)Promise方法race()
(5)Promise方法finally()
3.Promise的使用场景
(1)异步请求
(2)定时器
(3)动画效果
(4)多个异步操作的并行执行
(5)复杂的异步操作流程控制
4.Promise.all和Promise.race的区别
(1)Promise.all
(2)Promise.race
5.总结
本文主要讲解JavaScript异步编程中Promise的理解、基本用法和使用场景等等。
1.对Promise的了解
(1)介绍
Promise是JavaScript中用于处理异步操作的一种机制。它是一个代表了异步操作最终完成或失败的对象。Promise提供了更好的错误处理机制,并支持链式调用,避免了传统异步编程中的回调地狱问题。
Promise对象有三种状态:pending(进行中)、fulfilled(已成功resolved)和rejected(已失败),状态一旦改变就不会再变。
(2)Promise 的优缺点
优点:
链式调用:.then()
方法返回一个新的 Promise,允许你进行链式调用,避免回调地狱。
错误处理:.catch()
方法允许你集中处理 Promise 链中发生的错误。
组合能力:Promise 提供了多种组合多个 Promise 的方法,如 Promise.all()
、Promise.race()
等,使得处理多个异步操作变得更加容易。
缺点:无法取消Promise,一旦新建就会立即执行,无法中途取消;如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
2.Promise的基本用法
Promise的基本用法包括其构造函数、then()、catch()、all()、race()、finally()方法。
(1)创建Promise对象
使用new Prommise创建Promise对象
const promise = new Promise((resolve,reject)=>{
if(resolve){
resolve("123");
}else{
reject(error);
}
});
console.log(promise);
使用Promise.resolve()创建一个fulfilled状态的Promise对象
Promise.resolve("haha").then(value=>{
console.log(value); // haha
});
使用Promise.reject()创建一个rejected状态的Promise对象
Promise.reject(new Error("我错了,请原谅!!"));
(2)Promise方法then()
then()方法用于指定Promise成功或失败时的回调函数,接受两个参数:第一个参数是Promise成功时的回调函数,第二个参数是Promise失败时的回调函数(通常省略,使用catch
方法处理错误)。
const promise = new Promise((resolve,reject)=>{
if(resolve){
resolve();
}else{
reject(error);
}
});
promise.then(()=>{
console.log('resolved');
},()=>{
console.log('rejected');
});
(3)Promise方法catch()
catch
方法用于捕获Promise执行过程中的错误,并处理它们。它是.then(null, rejection)
的语法糖,相当于then方法的第二个参数。
promise.catch(error=>{
console.log(error);
});
(4)Promise方法all()
all()方法可以完成并行任务,它接受数组,每项数组都是一个Promise对象。数组中Promise的状态都是resolved时,all方法的状态就会变成resolved;如果有一个状态变为rejected,all方法的状态就会编程rejected。成功状态的结果是一个结果数组,失败状态结果是最先被reject状态的值。
Promise.all([
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve("任务1完成");
},2000)
}),
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve("任务2完成");
},1000)
}),
new Promise((resolve, reject)=>{
setTimeout(()=>{
reject("任务3出错");
},3000)
})
]).then(res=>{
console.log(res);
});
(4)Promise方法race()
race()方法和all()方法一样,不同的是不论状态resolved或rejected,最先执行的事件执行完之后,直接返回该promise对象的值。
Promise.race([
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve("任务1完成");
},2000)
}),
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve("任务2完成");
},1000)
}),
new Promise((resolve, reject)=>{
setTimeout(()=>{
reject("任务3出错");
},3000)
})
]).then(res=>{
console.log(res); // 任务2完成
});
(5)Promise方法finally()
finally
方法会在Promise执行结束后(无论是fulfilled或者rejected)执行,不接受任何参数,通常用于清理工作,如关闭文件描述符、释放资源等。
.finally(()=>{
console.log('Promise结束');
});
3.Promise的使用场景
Promise在前端开发中有广泛的应用场景,主要包括以下几个方面:
(1)异步请求
在前端开发中,经常需要进行异步请求,如发送HTTP请求获取数据。使用Promise可以更好地处理这些异步请求,通过Promise的链式调用可以更清晰地表达异步操作之间的依赖关系。
function promiseFunction() {
return new Promise((resolve, reject) => {
setTimeout(function() {
const success = true; // 模拟操作成功或失败
if (success) {
resolve('成功获取数据');
} else {
reject('获取数据失败');
}
}, 2000);
});
}
promiseFunction().
then(result => {
console.log("成功", result); // 成功 成功获取数据
})
.catch(result => {
console.log("错误", result)
});
(2)定时器
Promise可以与定时器结合使用,通过Promise的resolve和reject方法来控制定时操作的执行结果。
(3)动画效果
Promise可以用于管理动画效果的执行顺序和完成状态。通过Promise的链式调用,可以按照预定的顺序执行动画效果,并在动画完成后执行回调函数。
(4)多个异步操作的并行执行
Promise提供了Promise.all
方法,可以将多个Promise对象包装成一个新的Promise对象,当所有的Promise对象都完成时,新的Promise对象才会被解析。这样可以方便地实现多个异步操作的并行执行。
(5)复杂的异步操作流程控制
Promise提供了丰富的方法,如then、catch、finally等,可以灵活地组合和控制异步操作的执行流程。
4.Promise.all和Promise.race的区别
(1)Promise.all
接收一个包含多个Promise的数组(或类数组对象)作为参数,并返回一个新的Promise。
只有当数组中的所有Promise对象都成功完成时(即状态都变为fulfilled),返回的Promise对象才会成功完成,并将所有Promise的结果作为一个数组返回。如果数组中的任何一个Promise对象失败(即状态变为rejected),则返回的Promise对象会立即失败,并将第一个失败的Promise的原因作为失败原因返回。
适用于需要等待所有异步操作都成功完成后再进行下一步操作的场景。
(2)Promise.race
同样接收一个包含多个Promise的数组(或类数组对象)作为参数,并返回一个新的Promise。
这个返回的Promise会在数组中的任意一个Promise状态变为fulfilled或rejected时被解决或拒绝,且以第一个被解决的Promise的结果作为其结果返回。如果数组中的所有Promise都被拒绝,则返回的Promise将会以最先被拒绝的Promise的原因作为其原因拒绝。
适用于设置超时机制或只关心第一个完成的异步操作的场景。如下例子:
// race()
function timeoutPromise(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('操作超时'));
}, time);
});
}
// 使用Promise.race()来监听哪个Promise先完成
Promise.race([
longRunOperation(), // 长时间运行的操作
timeoutPromise(2000) // 2秒后超时的Promise
])
.then(result => {
console.log(result); // 如果longRunningOperation在2秒内完成,则打印'操作完成'
})
.catch(error => {
console.error(error.message); // 如果timeoutPromise先完成(即超时),则打印'操作超时'
})
5.总结
Promise是JavaScript中处理异步操作的一种强大机制,它通过提供清晰的状态管理和链式调用,极大地简化了异步编程的复杂度。Promise的基本用法包括构造函数、then方法、catch方法和finally方法等,它们共同构成了Promise的核心功能。Promise在前端开发中有广泛的应用场景,包括异步请求、定时器、动画效果、多个异步操作的并行执行和复杂的异步操作流程控制等。了解Promise的基本用法和使用场景,以及Promise.all和Promise.race的区别,对于编写高效、可靠的异步代码至关重要。