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产生任何实质性的影响

相关内容

热门资讯

安卓手机系统流畅版,极致性能与... 你有没有发现,最近你的安卓手机用起来是不是特别顺滑?没错,就是那种点屏幕就立刻响应的感觉,简直让人爱...
forest安卓系统换到苹果,... 你有没有想过,手机操作系统就像是我们生活中的不同道路,有时候,你可能觉得一条路走得太久了,想要换一条...
华为鸿蒙系统安卓平板,开启智能... 亲爱的读者们,你是否也像我一样,对科技圈的新鲜事儿充满好奇?今天,我要和你聊聊一个最近在科技圈掀起波...
安卓系统藏族软件下载,精选安卓... 安卓系统藏族软件下载:探索藏族文化的数字新篇章在数字化时代,手机已经成为我们生活中不可或缺的一部分。...
显示安卓系统耗电大,深度剖析原... 手机电量总是不够用?是不是觉得安卓系统耗电特别大?别急,今天就来给你揭秘安卓系统耗电的秘密,让你手机...
抽取原装安卓系统驱动,深度挖掘... 你有没有遇到过这种情况?手机里的安卓系统突然卡顿,或者某个应用突然罢工,这时候你是不是想给它来个“大...
安卓系统手机游戏排行,热门游戏... 你有没有发现,最近你的手机里是不是又多了一款游戏?没错,安卓系统手机游戏排行又更新了!今天,就让我带...
安卓系统叫AR 特效,安卓系统... 你知道吗?最近在安卓系统上出现了一个超级酷炫的新功能,它就是AR特效!是不是听起来就让人兴奋不已?那...
安卓系统特有的功能,解锁智能生... 你知道吗?安卓系统这个家伙,简直就是智能手机界的“全能选手”。它不仅拥有丰富的应用市场,还能给你带来...
iqoo 安卓系统王者跳帧,王... 最近有没有发现你的iqoo手机在玩王者荣耀时突然卡顿,画面跳帧,简直让人抓狂啊!别急,今天就来给你揭...
安卓系统平板画图,创意无限的艺... 你有没有想过,用平板画图竟然也能这么有趣呢?尤其是当你手握安卓系统平板的时候,那感觉简直就像拥有了整...
安卓系统韩文变成中文,安卓系统... 你是不是也遇到过这种情况?手机里突然冒出了韩文,而你却一头雾水,完全看不懂?别急,今天就来给你详细解...
国内邮箱注册安卓系统,轻松掌握... 你有没有想过,为什么你的手机里会有那么多邮箱呢?是不是每次注册新账号,都感觉像是在进行一场数字版的“...
苹果系统和安卓系统合作,跨界合... 你知道吗?最近科技圈可是炸开了锅,因为苹果系统和安卓系统竟然要联手合作啦!这可不是闹着玩的,两个在智...
安卓系统怎么篡改位置,轻松伪装... 你有没有想过,手机里的位置信息竟然也能被篡改?没错,就是那个我们平时用来导航、找餐馆、定位好友的安卓...
kindle 刷原生安卓系统,... 亲爱的读者们,你是否也有过这样的经历:拥有一台Kindle,却因为系统不够流畅而感到烦恼?别担心,今...
安卓点歌系统连电脑,打造个性化... 你有没有想过,你的安卓手机里的点歌系统竟然可以和电脑无缝连接呢?这听起来是不是很神奇?没错,今天就要...
那个电视搭载安卓系统,智能娱乐... 你有没有想过,家里的电视竟然也能搭载安卓系统?没错,就是那个曾经只存在于手机和平板电脑上的操作系统,...
安卓系统反黄软件,净化网络环境 你有没有发现,随着智能手机的普及,我们每天的生活越来越离不开这个小小的屏幕了。但是,你知道吗?在这个...
安卓怎么测试系统好坏,安卓系统... 你有没有想过,你的安卓手机是不是真的像你想象中那么强大呢?别急,今天就来给你揭秘,怎么测试安卓系统的...