Promise介绍和详解
创始人
2025-05-28 17:00:05
0

Promise

Promise

        - Promise可以帮助我们解决异步中的回调函数的问题

        - Promise就是一个用来存储数据的容器

                它拥有着一套特殊存取数据的方式

                这个方式使得它里边可以存储异步调用的结果

创建promise

// 创建Promise
const promise = new Promise(executor)

是一个回调函数,进一步创建Promise时需要一个exexutor(执行器)为参数,执行器是一个回调函数,进一步调用大概长这个样子

// 创建Promise
const promise = new Promise((resolve, reject) => {})

回调函数再执行时会收到两个参数,两个参数都是函数,第一个函数通常命名为resolve,第二个函数通常会命名为reject,向Promise中存储值得关键就在于这两个函数,可以将想要存储到Promise中的值作为函数的参数传递,

// 创建Promise
const promise = new Promise((resolve, reject) => {resolve("哈哈哈哈")
})
console.log(promise)

两个函数:

  1. resolve用来存储运行正确时的数据
  2. reject用来存储运行出错时的错误信息

我们使用Promise时需要根据不同的情况,调用不同的函数来存储不同的数据;

Promise中存储的主要是异步调用的数据,也就是本来需要回调函数来传递的数据。

在Promise中,可以直接调用异步代码,在异步代码执行完毕后直接调用resolve或reject来执行结果存储到Promise中,这就解决了易怒代码无法设置返回值的情况,如下:

// 创建Promise
const promise = new Promise((resolve, reject) => {setTimeout(() => {resolve("哈哈哈")}, 10000)
})
console.log(promise)

上述代码中setTimeout实现了一个异步调用,定时器会在10秒后执行,并且调用resolve将“哈哈”存储到promise中;

获取Promise中的数据

then

then是Promise的实例方法,通过改方法可以获取到Promise中存储的数据,它需要一个回调函数作为参数,Promise中存储的数据会作为回调函数的实参返回给我们

const promise = new Promise((resolve, reject) => {setTimeout(() => {resolve("哈哈哈")}, 1000)
})promise.then((data) => {console.log(data)  // 打印结果为"哈哈"
})

注意:这种方式只适用于读取通过reslove存储的数据,如果存储数据时出现了错误,或者是通过reject存储的数据,这种方式是无法读取的

const promise = new Promise((resolve, reject) => {// 出错的数据throw new Error("出错了")setTimeout(() => {resolve("哈哈哈")}, 1000)
})promise.then((data) => {console.log(data)  // 打印结果为"哈哈"
})
const promise = new Promise((resolve, reject) => {   setTimeout(() => {// 通过reject来添加reject("哈哈哈")}, 1000)
})promise.then((data) => {console.log(data)  // 打印结果为"哈哈"
})

上述两种情况均无法读取到数据,且控制台会在运行时候报错

第一种Promise的代码出错时,应该为其指定第二个参数来处理数据

第二种通过reject来添加数据时,添加的应该是有问题的数据,而不是正常数据

then的第二个参数依然是一个回调函数,两个回调函数的结构是相同的,不同点在于第一个回调函数在resolve添加数据,即没有异常时候被调用,而第二个函数会在出现错误(或者通过reject存储数据)时调用

const promise = new Promise((resolve, reject) => {   setTimeout(() => {// 通过reject来添加reject("哈哈哈")}, 1000)
})promise.then((data) => {console.log(data)  // 打印结果为"哈哈"
},(err) => {console.log("出错了", err)
})
const promise = new Promise((resolve, reject) => {   throw new Error("主动抛出错误")setTimeout(() => {resolve("哈哈哈")}, 1000)
})promise.then((data) => {console.log(data)  // 打印结果为"哈哈"
},(err) => {console.log("出错了", err)
})

上面的示例中,then的第二个回调函数会执行

执行时异常信息或通过reject返回的数据作为参数传递

开发过程中,then的第二个回调函数通常会用来编写异常        在Promise中维护着两个隐藏的值PromiseResult和PromiseState,PromiseResult是Promise中真正存储值得地方,在Promise中无论是通过resolve、reject还是报错时得异常信息都会存储到PromiseResult中,PromiseState用来表示Promise中值的状态,

Promise一共有三种状态:pending、fulfilled、rejected此时Promise中没有任何值,fulfilled是Promise的完成状态,此时表示值已经正常存储到了Promise中(通过reslove)。rejected表示拒绝,此时表示值是通过reject存储或是执行时出现了错误

当我们调用Promise方法,相当于为Promise设置了一个回调函数,

then中的回调函数不会立即执行,而是在Promise的PromiseState发生变化才会执行。

如果PromiseState从pending变成了fulfilled则then的第一个回调函数执行,且PromiseResult的值作为参数传递给回调函数

如果PromiseState从pending变成了rejected则then的第二个回调函数执行,且PromiseResult的值作为参数传递给回调函数

总结:

Promise中维护了两个隐藏属性:

        PromiseResult

                - 用来存储数据

PromiseState

        - 记录Promise的状态(三种状态)

                pending (进行中)

                fulfilled (完成) 通过resolve存储数据

                rejected  (拒绝,出错了)  出错了或通过reject存储数据时

        - state只能修改一次,修改以后永远不会再变

流程总结:

当Promise创建时,PromiseState初始值为pending

        当通过resolve存储数据时候 PromiseState 变为fulfilled(完成)

                PromiseResult变为存储的数据

        当通过reject存储数据或出错时 PromiseState 变为rejected(拒绝,出错了)

                PromiseResult变为存储的数据 或者 异常对象

当我们通过then读取数据时,相当于为Promise设置了回调函数

        如果PromiseState变为fulfilled,则调用then的第一个回调函数来返回数据

        如果PromiseState变为rejected,则调用then的第二个回调函数来返回数据

 Catch

catch()用法和then类似,但是只需要一个回调函数作为参数

        catch()中的回调函数只会在Promise被拒绝时才调用

        catch()相当于then(null, reson => {} )  即第一个参数为null的then

        catch() 就是一个专门处理Promise异常的方法

const promise = new Promise((resolve, reject) => {   reject("出错了")
})// 出现异常,使用catch来读取数据
promise.catch(err => {console.log(err)
})

处理Promise时,如果没有对Promise中的异常进行处理(无论是then的二参数,还是catch),则异常信息总是会封装到下一步的Promise中进行传递,直到找到异常处理代码的位置,如果没有处理,则报错

这种设计方式使得我们可以在任意位置对Promise的异常进行处理,如下实例

function sum(a, b) {return new Promise((resolve, reject) => {if (Math.random() > 0.7) {throw new Error("出错了")}resolve(a + b)})
}sum(123, 456).then(result => sum(result, 777)).then(result => sum(result, 888)).then(result => console.log(result))

上述示例中,sum函数有几率会出现异常,但我们并不确定何时出现异常,

因为在出现异常后所有的then在异常处理前都不会执行,所以可以将catch写在调用链的最后,这样无论哪一步出现异常,我们都可以在最后统一处理

sum(123, 456).then(result => sum(result, 777)).then(result => sum(result, 888)).then(result => console.log(result)).catch(err => console.log("出错了", 88888))

当然如果我们想在中间处理异常也是可以的,只是需要注意在链式中间处理异常时候,由于后续还有then要执行,所以一点过不要忘了来考虑是否需要在catch中返回一个结果供后续的promise使用:

function sum(a, b) {return new Promise((resolve, reject) => {if (Math.random() > 0.7) {throw new Error("出错了")}resolve(a + b)})
}sum(123, 456).then(result => sum(result, 777)).catch(err => {// 在调用链的中间处理异常console.log("出错了,选择忽略这个错误,重新计算")// 返回一个结果供后续运算return sum(123, 456)}).then(result => sum(result, 888)).then(result => console.log(result))

需要注意的是。在Promise正常执行的情况下如果遇到catch,catch是不会执行的,此时Promise中的结果会自动传递给下一个Promise供后续使用

Finally

  • 无论是正常存储数据还是出现异常了,finally总会执行
  • 通常在finally中定义一些无论Promise正常执行与否都需要处理的工作
  • finally的回调函数不接收任何参数
  • finally的返回值不会成为下一步的Promise中的结果
  • finally只是编写一些必要执行的代码,不会对Promise产生任何实质性的影响

相关内容

热门资讯

扫房神器2安卓系统,打造洁净家... 你有没有发现,家里的灰尘就像小精灵一样,总是悄悄地在你不注意的时候跳出来?别急,今天我要给你介绍一个...
安卓完整的系统设置,全面掌控手... 亲爱的手机控们,是不是觉得你的安卓手机用久了,功能越来越强大,但设置却越来越复杂?别急,今天就来带你...
电视安卓系统是几代机子,揭秘新... 你有没有想过,家里的电视是不是已经升级到了最新的安卓系统呢?别小看了这个小小的系统升级,它可是能让你...
安卓系统隐私有经常去,系统级防... 你知道吗?在咱们这个数字化时代,手机可是我们生活中不可或缺的好伙伴。但是,你知道吗?这个好伙伴有时候...
安卓10系统断网软件,轻松实现... 你有没有遇到过这种情况?手机突然断网了,明明信号满格,却连不上网,急得你团团转。别急,今天就来给你揭...
安卓可以改什么系统版本,体验全... 你有没有想过,你的安卓手机其实可以像换衣服一样,换一个全新的“系统版本”呢?没错,这就是今天我们要聊...
最好的平板游戏安卓系统,畅享指... 亲爱的游戏迷们,你是否在寻找一款能够让你在安卓平板上畅玩无忧的游戏神器?别急,今天我就要给你揭秘,究...
华为安卓系统卡顿解决,华为安卓... 你是不是也遇到了华为安卓系统卡顿的问题?别急,今天就来给你支几招,让你的华为手机重新焕发活力!一、清...
安卓建议升级鸿蒙系统吗,探讨鸿... 亲爱的安卓用户们,最近是不是被鸿蒙系统的新鲜劲儿给吸引了?是不是在犹豫要不要把你的安卓手机升级成鸿蒙...
安卓如何变苹果系统桌面,桌面系... 你有没有想过,把你的安卓手机变成苹果系统桌面,是不是瞬间高大上了呢?想象那流畅的动画效果,那简洁的界...
windows平板安卓系统升级... 你有没有发现,最近你的Windows平板电脑突然变得有些不一样了?没错,就是那个一直默默陪伴你的小家...
安卓系统扩大运行内存,解锁更大... 你知道吗?在科技飞速发展的今天,手机已经成为了我们生活中不可或缺的好伙伴。而手机中,安卓系统更是以其...
安卓系统怎么改变zenly,探... 你有没有发现,你的安卓手机上的Zenly应用最近好像变得不一样了?没错,安卓系统的大手笔更新,让Ze...
英特尔安卓子系统,引领高效移动... 你有没有想过,手机里的安卓系统竟然也能和电脑上的英特尔处理器完美结合呢?这可不是天方夜谭,而是科技发...
永远会用安卓系统的手机,探索安... 亲爱的手机控们,你是否也有那么一款手机,它陪伴你度过了无数个日夜,成为了你生活中不可或缺的一部分?没...
有哪些安卓手机系统好用,好用系... 你有没有发现,现在手机市场上安卓手机的品牌和型号真是琳琅满目,让人挑花了眼?不过别急,今天我就来给你...
卡片记账安卓系统有吗,便捷财务... 你有没有想过,用手机记账是不是比拿着小本本记录来得方便多了?现在,手机上的应用层出不穷,那么,有没有...
武汉摩尔影城安卓系统APP,便... 你有没有想过,一部手机就能带你走进电影的世界,享受大屏幕带来的震撼?今天,就让我带你详细了解武汉摩尔...
联想刷安卓p系统,畅享智能新体... 你有没有发现,最近联想的安卓P系统刷机热潮可是席卷了整个互联网圈呢!这不,我就迫不及待地来和你聊聊这...
mac从安卓系统改成双系统,双... 你有没有想过,你的Mac电脑从安卓系统改成双系统后,生活会有哪些翻天覆地的变化呢?想象一边是流畅的苹...