详解 ES6中 Promise 构造函数的使用

Promise是ES6为解决异步回调地狱引入的机制,它有三种状态:pending、fulfilled和rejected。Promise对象封装异步操作,通过resolve和reject切换状态。then方法用于处理成功或失败的情况,Promise.all用于处理多个Promise实例,所有实例成功才触发then,否则触发catch。
摘要由CSDN通过智能技术生成


前言

Promise 是ES6 新增的一个异步调用解决方案,它的出现是为了解决异步函数的 回调地狱 的问题。

在这里插入图片描述

什么是 Promise?

从语法层面 来说 Promise 是一个构造函数,从功能上来说 Promise 对象用来封装一个异步操作,并且可以获得请求的结果数据。参数接收一个 回调函数(也被叫做执行器函数用于执行异步操作),接收两个参数 resolve reject,当请求成功会自动调用 resolve失败则调用 reject。并且会将执行结果返回给 Promise 的实例对象。

一个 Promise 对象代表一个在这个 Promise 被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。

同时 Promise 又有承诺的意思,意思是,约定好一件事,如果当下不能完成,后续一定会去处理完成,表示暂未完成,未来一定会完成的一种状态。


Promise 的几种状态

一个 Promise 对象拥有 三种状态,在同一时刻必然处于以下几种状态之一:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled):意味着操作成功完成。
  • 已拒绝(rejected):意味着操作失败。

1.pengding:意思是 待定的,即将要发生的, 这是 Promise 的初始化状态 ,如果创建 Promise 对象的时候,且没有调用resolve或者是reject方法 ,这时候状态就会为 pending,,这个初始化状态会随着你调用了 resolve,或者是reject函数而切换到另一种状态。

待定状态的 Promise 对象要么会通过一个值被兑现,要么会通过一个原因(错误)被拒绝。当这些情况之一发生时,我们用 Promise 的 then 方法排列起来的相关处理程序就会被调用。如果 Promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序也同样会被调用,因此在完成异步操作和绑定处理方法之间不存在竞态条件。

在这里插入图片描述

2.fulfilled: 表示成功了解决了,并且兑现了 “承诺”, 状态已经从 pending 转变成 fulfilled 了,要实现从 pending fulfilled 的转变,需要在创建Promise对象时,在函数体中调用了resolve方法。

在这里插入图片描述
3.rejected: 表示失败了,虽然得到了返回结果,但并不是我想要的,代码拒绝往后执行。要实现从pendingrejected的转换,只需要在创建Promise对象时,调用reject函数。

在这里插入图片描述

最后不管是成功还是失败,都会有一个结果,通常我们将成功数据称为 value,失败的数据称为 reason,并且当 Promise 的状态改变后,就不会再变了,是不可逆的。状态的改变伴随着事件的触发,一个 Promise 的状态只能被改变一次。

console.dir(Promise)

浏览器输出 Promise 原型对象,可以看见在它身上有很多属性方法。
在这里插入图片描述
Promise 的实例身上都会有 一个 then 方法,如上图,该方法有两个函数作为参数 .then(resolvedFunc, rejectedFunc)

  • resolvedFunc 状态成功时执行的回调函数
  • rejectedFunc 状态失败时执行的回调函数

所以说,如果返回的值,依然是一个 Promise ,那么就可以进行 then 方法的 链式调用


拆分细解 Promise

Promise 构造函数接收一个 callback 作为参数,这个 callback 被称为回调函数,用于执行异步操作:

let pro = new Promise(() => { })
console.log(pro);     // Promise {<pending>} 所有 Promise 初始状态都为 pending

回调函数接收两个参数 resolve, reject ,它们的类型都为 一个 function

let pro = new Promise((resolve, reject) => {
//执行异步任务请求的操作
})
console.log(pro);

异步请求如果,成功就调用 resolve,失败就调用 reject。最终的返回数据结果 ,会返回到 实例对象 pro上。

let pro = new Promise((resolve, reject) => {
//执行异步任务请求的操作
// 请求处理成功后调用 resolve(value)  把成功的数据返回出去
//请求处理如果 失败后调用 reject(reason) 把失败的信息也给返回出去

})
console.log(pro);

最后实例对象 pro 身上会有 一个 then 方法,同样可以接收两个回调函数作为参数。一旦在 Promise 函数中 成功调用了 resolve() 将会执行 then 中第一个回调函数,失败则会执行 then 的第二个回调函数:

pro().then(
    value => { console.log(value)},
    reason => { console.log(reason)}
)

流程图例:
在这里插入图片描述

案例

let pro = new Promise((resolve, reject) => {
    let a = 10;
    setTimeout(() => {
        if (a > 5) {
            resolve(a)
        } else {
            reject(a)
        }
    }, 5000)
})
console.log(pro);
pro.then(
    value => { console.log("成功的" + value) },
    reason => { console.log("失败的" + reason) }
)

当我们案例中 a 大于5的时候, resolve 方法调用,返回数据, 在 then 方法中第一个 value 回调参数输出成功返回的值。
在这里插入图片描述

反之,当我们案例中 a 小于5 的时候, reject 方法调用,返回数据, 在 then 方法中 第二个 reason 回调参数输出失败返回的值。
在这里插入图片描述

Promise 实例化 执行流程图例:

在这里插入图片描述
使用 catch 替代 then 的第二个回调

虽然 then 方法,可以接收两个参数,用来输出 成功 和 失败的信息,但是建议 then 方法只用来输出 成功 的信息,失败的信息可以用 catch() 来输出,这样显得更具语义化以及结构化,更加的清晰。

如:

let pro = new Promise((resolve, reject) => {
    let a = 4;
    setTimeout(() => {
        if (a > 5) {
            resolve(a)
        } else {
            reject(a)
        }
    }, 5000)
})
console.log(pro);
pro.then(value => {
    console.log("成功的" + value)
}).catch(reason => {
    console.log("失败的" + reason) 
})

需注意一点: Promise 的那个回调函数,实际上是一个 同步回调函数,只是当遇到 resolve() 或者 reject() ,时会调用 then方法,而 then ,方法是属于以前的回调,所以 then 方法中的 回调 是异步回调函数。如下案例,分析输出的顺序 。

let pm = new Promise((resolve, reject) => {
  console.log(1);
  resolve();
  console.log(2);
});
console.log(3);
pm.then(() => {
  console.log(4);
});
console.log(5);

案例印证了上面的观点。
在这里插入图片描述


Promise all()方法

all 方法用来将 多个 Promise 实例包裹成一个新的 Pomise 实例,它接收 一个数组作为参数,数组中,传入 N个 Promise 对象,返回一个新的 Promise。

let p1 = new Promise((resolve, reject) => {
  setTimeout(function () {
    resolve(1);
  }, 1000);
});
let p2 = new Promise((resolve, reject) => {
  setTimeout(function () {
    resolve(2);
  }, 5000);
});
let p3 = new Promise((resolve, reject) => {
  setTimeout(function () {
    resolve(3); 
  }, 200);
});
Promise.all([p1, p2, p3])
  .then((values) => {
    console.log(values);   //  [1, 2, 3]
  })
  .catch((reason) => {
    console.log(reason);
  }); 

上面案例中,有 3个 Promise 实例对象的回调函数,通过 all 方法,将多个 Promise 进行包裹处理,异步的执行顺序,会按照参数中,所定义的顺序来进行执行。

值得注意:只有当数组中的 Promise 全部都为成功 状态的时候,才会触发 then 方法,若其中有一个为失败的状态,则就会 直接触发 catch 方法返回失败的信息,不会触发,then 方法。

then()方法 返回一个新的 Promise 时的状态由什么决定?

返回的新的 Promise 的状态,主要是根据 前一个 Promise 对象的返回值来决定的。

大致分为以下几种状态情况。

  • 若抛出异常,新 Promise 状态变为 rejected,reason 为抛出的异常原因
  • 若返回非 Promise 的值,新 promise 状态变为 resolved,value 为返回的值
  • 若返回新的 Promise 结果就成为新 promise 的结果

总结

以上就是给大家 带来的 ES6 中 Promise 的概念用法,如今越来越多的封装框架化,确实带来了很多的便利,但是也不要忘记了掌握很多的原生的语法逻辑,有时候,回过头来,再看一看原生的东西,又是另一番感觉和领悟!


🚵‍♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼‍♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旧梦星轨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值