JS进阶 | 关于Promise

89 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

前面说到了关于Axios以及工程化时对于Axios的封装,他的核心就是基于Promise封装的HTTP客户端。

作为一个前端人,当然要深入的了解Promise以及原理

image.png

上图很清晰的展示了JS中同步和异步的区别,Promise正是异步编程的一种解决方案(ES6 新增)

Promise,词如其名,承诺,就是承诺在一段时间后会返回一个结果,任何其他操作都无法改变这个状态

核心

3种状态: 对象的状态不受外界影响

  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)

2种状态改变: 一旦状态改变,就不会再变

  • Pending -> Fulfilled(成功)
  • Pending -> Rejected(失败)

使用场景

  • 解决异步问题

  • 解决回调地狱(callback hell)

    之前异步是通过回调函数进行处理。层级很多时,很容易进入到回调地狱中,维护也很困难: 有多层的异步操作,

setTimeout(function() {
    setTimeout(function() {
        setTimeout(function() {

        },1000);
    },1000);
},1000);
  • 可以进行多个并发请求

优点:

  • 链式操作减低了编码难度(比如.then().then().catch())
  • 代码的可读性增强

弊端:

  • 无法取消 Promise,一旦新建它就会立即执行,无法中途取消sh
  • 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
  • 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成

代码实现

  • resolve:异步成功后的回调
  • reject:异步失败后的回调
let p = new Promise((resolve, reject) => {
    //进行异步操作
    setTimeout(() => {
        console.log('执行完毕');
        resolve('resolve:成功状态');
    }, 2000);
})

p.then((res) => {
    console.log(res);
})
.then((res) => {
    console.log(res);
})
.catch((err) => {
    console.log(err);
})

  • then() 实例状态发生改变时的回调
  • catch() 发生错误执行的回调
  • finally() 不论 Promise 对象最后状态如何,都会执行的操作

Promise的方法

const p = Promise.all([p1, p2, p3]);
  • Promise.all()

    并行执行多个异步操作(将多个 Promise 实例,包装成一个新的 Promise 实例)

  • Promise.race()

    p1、p2、p3之中有一个实例先改变状态,p的状态就跟着改变

  • Promise.allSettled()

  • Promise.resolve()

    将现有对象转为 Promise 对象

  • Promise.reject()

  • Promise.try()