
通俗易懂之Promise!

都知道javaScript代码是单线程执行的,就是这个原因,导致了JavaScript中所有的网络操作,浏览器事件,都必须满足异步执行的要求,此时Promise就诞生了。简单来说Promise是一种处理异步请求的解决方案。
初始Promise
Promise三种状态
Promise 是一个构造函数,需要使用new关键字生成实例
1 | let p = new Promise(() => { |
这里写了一个简单的Promise,输出如下结果:
可以看出在Promise未指定任何状态时,返回的状态为pending(等待状态),还有两段代码:
1 | let p = new Promise((resolve, reject) => { |
1 | let p = new Promise((resolve, reject) => { |
两段代码的结果分别为:
不难看出,Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:
- resolve :异步操作执行成功后的回调函数,指定了成功的状态为fulfiled(成功状态),且成功状态的值为你设置的ok
- reject:异步操作执行失败后的回调函数,指定了失败的状态为rejected(失败状态),且失败状态的值为你设置的err
注:失败的回调这里控制台有报错信息,这里不是我们的代码错误,是Promise 的失败回调函数抛出了一个错误。
Promise状态不能被改变
有这么一段代码:
1 | let p = new Promise((resolve, reject) => { |
此时结果:
由此得出Promise状态一旦改变就不会再变了,创造Promise实例后它会立即执行
.then
.then的链式调用
有这么一个需求:
请求三次数据,请求第一次的参数为params=321,而后两次参数分别为前一次返回的结果,是你你会如何实现?
普通方式解决如下:
1 | getData('/api/a/1?params=321',(res1) => { |
以上这种方式就是传说中的回调地狱–>回调里面套回调。
此时我们使用Promise来优化上述代码:
1 | getData('/api/a/1?params=321').then((res1)=>{ |
被优化后的代码是通过.then解决后的结果,也是成功的解决了回调地狱的问题。
又有两段代码:
1 | let p = new Promise((resolve, reject) => { |
得到结果为
1 | let p = new Promise((resolve, reject) => { |
结果为:
因为链式调用的结果上述代码中的p.then
也是一个Promise,由此得出:
如果Promise的then方法的成功或失败返回是非Promise,那么then方法返回的Promise实例就为成功的,值为return的那个非Promise值,如果返回的是Promise,那么then方法返回的Promise实例就取决于上个Promise的返回结果。
.then的两个参数
.then可以接收两个参数,并且两个参数都是回调函数,有这么一段代码:
1 | let p = new Promise((resolve, reject) => { |
上述代码当你随意切换name的值会发现,你使用resolve
指定为成功的结果时,then方法就会执行第一个成功回调,若你使用reject
指定为失败的结果时,then方法就会执行第二个失败回调。
.catch
首先我来演示一个错误:
1 | let p = new Promise((resolve, reject) => { |
如上述代码所示,我定义了一个为定义的变量a,运行结果如下图:
可以看出报错终止了代码的运行,,错误回调并没捕获错误的结果。此时我换成catch:
1 | let p = new Promise((resolve, reject) => { |
结果为:
也就是说进入catch中时,把错误原因传到参数中,即便有错误代码也不会报错了,与try/catch相似。
Promise.all()
Promise下的all方法接受一个由多个Promise组成的数组,所有Promise结果成功,才返回成功的Promise回调,上代码:
1 | function getLunbo() { |
结果如下
如果全部成功,就返回所有成功结果组成的数组,如果其中一个Promise返回失败的结果则:
Promise.any()
Promise下的any方法也接受一个由多个Promise组成的数组,一个Promise返回结果为成功,整体就返回成功的promise,所有的都失败才返回失败的promise。
1 | let x1 = new Promise((resolve, reject) => { |
结果为
如果都是失败的Promise则:
Promise.race()
race 赛跑的意思,以第一个有结果的promise为主,成功即为成功,失败即为失败
1 | const p1 = new Promise((resolve, reject) => { |
上述代码执行最快的是第一个,所以Promise.race([p3, p1, p2]);
的结果取决于第一个,第一个为pending
,result的结果就是pending
,为成功就成功,为失败就失败。
Promise.finlly()
1 | const p1 = new Promise((resolve, reject) => { |
不难看出,不管成功与否,失败与否都会执行finally(),且finally回调函数不接收参数
Promise.allSettled()
当所有的异步操作都有结果时,包装实例才结束,返回**成功的Promise,**目前我未曾用过这个方法,后续我将补充
1 | const promise1 = Promise.resolve(3); |
上述代码摘自MDN
Promise.resolve()
当Promise.resolve()中传入了非Promise,那么包裹对象返回成功的Promise,成功的结果为非Promise的值,如果传入的是Promise,那么包裹对象返回的结果为Promise返回的结果
Promise.reject()
直接指定为失败状态的Promise,返回一个带有拒绝原因reason参数的Promise对象。
anync与await
await 也是一个修饰符,只能放在async定义的函数内。可以理解为等待,等待成功的回调。
await必须写在async函数中,但是async函数中可以没有await
如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
1 | async function getData () { |
上述代码anync与await的基本使用,后续还会补充。
最后
关于Promise的总结 总结 **
Promise可以解决代码的回调地狱(回调里面套回调),从而简化代码
Promise可以解决异步的问题,但本身不能说Promise是异步的
anync与await是开发主流,可通过try…catch捕获异常
**
希望大家有所收获!!!!!!!!!!!!!!!!!!!!!!!!
- 标题: 通俗易懂之Promise!
- 作者: The局外人
- 创建于 : 2024-05-14 11:43:01
- 更新于 : 2023-09-05 13:02:38
- 链接: https://dragon-xjy.gitee.io/2024/05/14/通俗易懂之Promise/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。