Promise用法详解
1、构造函数Promise(excutor)
- excutor:
- Promise构造函数接受一个执行器作为参数(excutor,其实就是一个回调函数),在Promise构造函数执行时,会立即执行传入的excutor。
- excutor函数被调用时,会传入resolve, reject两个函数作为参数;当resolve函数被调用,Promise状态变更为fulfilled(完成);当reject函数被调用,Promise状态变更为rejected(失败)
- 如果excutor内部抛出异常,Promise状态将直接变更为rejected,错误对象将作为结果返回。
const p = new Promise((resolve, reject) => { console.log("excutor函数会被立即执行"); resolve("状态变更为:fulfilled"); // reject("状态变更为:rejected"); // throw new Error('报错,Promise状态将直接变更为rejected') });
2、状态
Promise一共有3中状态:
3、实例方法
- then(onFulfilled, onRejected)
- 作用:
- 为Promise注册onFulfilled和onRejected回调
- 返回新的promise,实现链式调用
- 新的promise将以回调函数返回值来resolve
- 特性:
- then方法本身会自动返回一个新的Promise对象,当然也可以手动在任意(onFulfilled或者onRejected)回调函数中返回一个Promise对象
const p = new Promise((resolve, reject) => { console.log("excutor函数会被立即执行"); resolve("状态变更为:fulfilled"); }); // then方法本身会返回一个promise p.then() .then() .then((res) => { console.log(res); //输出:状态变更为:fulfilled }); // then方法通过回调函数可以返回promise p.then( (res) => { return new Promise((resolve, reject) => { resolve("onFulfilled中返回的Promise"); }); }, (reason) => { return new Promise((resolve, reject) => { resolve("onRejected回调中也可以返回Promise"); }); } ).then((res) => { console.log(res); });
- then方法可以通过返回的Promise对象,实现链式调用
- 如果回调函数返回的是普通值,那么将会在下一个then中作为回调函数参数被接收
- 如果回调函数返回的是一个Promise, 下一个then方法将会等待这个Promise执行结束,并接收Promise的执行结果
const p2 = new Promise((resolve, reject) => { console.log("excutor函数会被立即执行"); resolve("状态变更为:fulfilled"); }); p2.then(res => { return new Promise((resolve, reject) => { setTimeout(() => { resolve('promise执行完毕') }, 1000); }) }).then(res => { console.log(res)//等待1秒钟,输出:promise执行完毕 })
- 如果没有传入回调函数,Promise将自动为then方法注册回调函数,并在回调函数中将接收到的值返回,传递给下一个then,实现值的穿透。
//没有给then注册回调,发生值穿透 const p3 = new Promise((resolve, reject) => { resolve(1); }); p3.then(2).then(4).then(console.log); //1
- then方法中不允许将本身返回的promise对象作为返回值
const p4 = p3.then(res => { // 不允许,将会报错 // TypeError: Chaining cycle detected for promise #<Promise> return p4 })
- catch(onRejected)
- 作用
- 给Promise添加onRejected回调
- 特性
- 返回一个新的Promise
- 新的Promise将以回调函数返回值来resolve
const promise = new Promise((resolve, reject) => { reject(100); }); promise .catch((reason) => { console.log(reason); //100 return 200; //catch函数返回值将作为新Promise的resolve结果 }) .then((res) => { // 新Promise执行结果 console.log(res); //200 });
- finally(finallyCallback)
- 作用
- 给Promise添加一个事件处理回调函数
- 特性
- 无论成功还是失败,都会调用传入的finallyCallback
- finallyCallback会返回一个新的Promise
- finallyCallback内部不能获取到Promise执行结果
const promise = new Promise((resolve, reject) => { resolve(100); }); promise .finally((res) => { console.log("finally回调函数无论成功或者失败,始终会被执行"); // finally回调函数内获取不到promise执行结果 console.log(res); }) .then((res) => { // finally回调函数返回一个新的promise,实现链式调用 console.log(res); });
4、静态方法
- Promise.all(promiseArray)
- 作用:
- 接受一个数组作为参数,将执行结果以数组形式顺序返回
- 并发执行数组中的promise对象
- 特性:
- 接受一个数组作为参数,数组元素可以是普通值,也可以是promise对象
- 执行结果以数组形式返回,数组中元素跟传入的promiseArray一一对应
- 如果传入的数组中元素是普通值,直接原样将对应值放入结果数组中
- 如果传入的数组中元素是promise对象,将并发执行对应的Promise对象,并等待执行结束,返回结果
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("p1"); }, 2000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve("p2"); }, 1000); }); const promiseAll = Promise.all([1, 2, promise1, 3, 4, promise2, 5]); promiseAll.then((res) => { //并发执行promise //执行结果与传入的数组一一对应 //会等待所有任务执行完毕之后统一返回结果 console.log(res); //[1,2,"p1",3,4,"p2",5] });
- 如果传入的数组中某一项执行失败,那么Promise将会执行失败
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("p1"); }, 2000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { reject('我这该死的温柔,居然执行失败了') }, 1000); }); const promiseAll = Promise.all([1, 2, promise1, 3, 4, promise2, 5]); promiseAll.then((res) => { // 任何一个任务执行失败 ,整个promise将执行失败 console.log(res); }).catch(e => { //任何一个任务失败,将导致整个Promise执行失败 console.log('fail',e) });
- Promise.allSettled(promiseArray)
非正式版,目前处于stage4阶段,尚未完全被浏览器支持
- 作用:
- 同Promise.all
- 特性:
- 等待数组中所有任务执行完毕,返回一个数组
- 无论成功还是失败,都会有返回结果
- 其它同Promise.all
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("p1"); }, 2000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { reject("我这该死的温柔,居然执行失败了"); }, 1000); }); const promiseAll = Promise.allSettled([1, 2, promise1, 3, 4, promise2, 5]); promiseAll .then((res) => { /** Promise.allSettled执行结果 [ { status: 'fulfilled', value: 1 }, { status: 'fulfilled', value: 2 }, { status: 'fulfilled', value: 'p1' }, { status: 'fulfilled', value: 3 }, { status: 'fulfilled', value: 4 }, { status: 'rejected', reason: '我这该死的温柔,居然执行失败了' }, { status: 'fulfilled', value: 5 } ] */ console.log(res); }) .catch((e) => { console.log("fail", e); });
- Promise.race(promiseArray)
- 作用
- 接受一个数组, 并发执行数组中的任务
- 谁执行块,就返回谁的结果,无论成功还是失败
- 一般用来做网络超时功能
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("p1"); }, 2000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve("p2"); }, 1000); }); const promise3 = new Promise((resolve, reject) => { // 假设500毫秒后网络超时 setTimeout(() => { reject("超时了"); }, 500); }); const promiseRace = Promise.race([promise1, promise2, promise3]); promiseRace .then((res) => { console.log(res); }) .catch((e) => { // 谁执行块,就返回谁 console.log("fail", e); });
- Promise.reject(reason)
- 作用:
- 返回一个状态为失败的Promise,并将失败信息传递给对应的处理方法
Promise.reject("rejected") .then((res) => { console.log('value', res); }) .catch((reason) => { // reason rejected console.log('reason', reason); });
- Promise.resolve(value)
- 作用:
- 接受一个值,返回一个Promise
- 特性:
- 如果value是一个普通值,则将普通值作为新Promise的resolve结果
- 如果value是一个Promise,则将value原样返回
Promise.resolve(100).then((res) => { console.log(res); //100 }); const promise = new Promise((resolve, reject) => { reject(200); }); promise .then((res) => { console.log(res); //200 });
作者:小灰🌾🐛
链接:https://juejin.im/post/6864111058891538445
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)