Promise学习记录

108 阅读6分钟

Promise学习记录

什么是Promise

Promise是一个类,意思为承诺、许诺、期约;

当我们需要的时候,给与调用者一个承诺,等会我会给你回调数据时,就可以创建一个Promise对象;

在通过New创建Promise对象时,我们需要传入一个回调函数,我们称之为Executor

  • 这个回调函数会被立即执行,并且传入另外两个回调函数 resolve and reject;
  • 当我们调用resolve回调函数是,会执行Promise对象的then方法传入的回调函数
  • 当我们调用reject回调函数是,会执行Promise对象的catch方法传入的回调函数

Promise的状态:

  • 待定(pending) : 初始状态,既没有对线,也没有被拒绝;

    当执行exector的代码是,处于该状态

  • 已兑现(fulfilled) : 意味着操作完成;

    执行了resolve时,处于该状态,Promise 已经被兑现;

  • 已拒绝(rejected) : 意味着操作失败;

    执行了reject时,处于该状态,Promise已经被拒绝;

const promise = new Promise((resolve, reject) => {
    resolve("成功")
    reject("拒绝")
})
promise.then(res => {
    console.log(res)
}).catch((err) => {
    console.log(err)
})

注:Promise状态一旦变更无法更改,在我们调用resolve的时候,如果resolve传入的值本身不是一个Promise,那么该Promise的状态变成兑现,在之后去调用reject时,已经不会有任何的响应了

resolve 不同值的区别

  • 如果resolve传入的是一个普通的值或者对象,那么这个值会做为then回调参数;
  • 如果resolve传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态
  • 如果resolve传入的是一个对象,并且这个对象有实现then方法,那么会执行then方法,并且根据then方法的结果来决定Promise的状态
const promise = new Promise((resolve, reject) => {
    resolve("成功")
})
promise.then(res => {
    console.log(res) //成功
}).catch((err) => {
    console.log(err)
})
const promise = new Promise((resolve, reject) => {
    resolve(new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve("第二个Promise的resolve")
        })
    }))
})
promise.then(res => {
    console.log(res) //第二个Promise的resolve
}).catch((err) => {
    console.log(err)
})
const promise = new Promise((resolve, reject) => {
    resolve({
        then:function (re, rj){
            re("我是带有then方法的对象")
        }
    })
})
promise.then(res => {
    console.log(res) //我是带有then方法的对象
}).catch((err) => {
    console.log(err)
})

then方法-接收两个参数

  • then方法是Promise对象上的一个方法(实例方法):

其实是放在Promise原型上的Promise.prototype.then

  • then方法接收两个参数

    1. fullfield的回调函数,当状态变成fulfilled时会回调的函数;
    2. reject的回调函数,当状态变成reject时会回调的函数;
console.log( Promise.prototype.then) //[Function: then]
​
promise.then(res => {
    console.log(res) //我是带有then方法的对象
}).catch((err) => {
    console.log(err)
})
//=================两者等价
promise.then(res => {
    console.log(res) //我是带有then方法的对象
},(err) => {
    console.log(err)
})
​

then方法-返回值

then方法的返回值是一个Promise,所以可以进行链式调用

Promise有三种状态,那么这个Promise处于什么状态呢?

? 当then方法中的回调函数本身在执行的时候,那么它处于pending状态

  • 当then方法中的回调函数返回一个结果时,那么它处于fulfilled状态,并且会将结果作为resolve的参数;

    ✓ 情况一:返回一个普通的值;

    ✓ 情况二:返回一个Promise;

    ✓ 情况三:返回一个thenable值;

  • 当then方法抛出一个异常时,那么它处于reject状态;

catch方法

  • catch方法是Promise对象上的一个方法(实例方法):

其实是放在Promise原型上的Promise.prototype.catch

catch方法-返回值

catch方法的返回值也是一个Promise对象,所以catch方法后面我们可以继续调用then方法或者catch方法“

const promise = new Promise((resolve, reject) => {
​
    reject("拒绝")
})
promise.then(res => {
    console.log(res) 
}).catch((err) => {
    console.log(err)//拒绝
}).then(res => {
    console.log("catch后面的then", res)// catch后面的then undefined
})
/* 运行结果:拒绝
catch后面的then undefined
*/

注意:catch传入的回调在执行完后,默认状态依旧会是已兑现状态

如果我们希望后续继续执行catch,那么需要抛出一个异常:

const promise = new Promise((resolve, reject) => {
    reject("拒绝")
})
promise.then(res => {
    console.log(res)
}).catch((err) => {
    console.log(err)//拒绝
    throw new Error("reject")
}).then(res => {
    console.log("catch后面的then", res)
}).catch(err=>{
    console.log("第二次catch", err.message)//第二次catch reject
})
​
/*运行结果
拒绝
第二次catch reject
*/

Promise其他方法

Finally 方法

  • finally实在ES9(ES2018)中新增的一个特性,表示无论Promise对象无论变成fulfilled还是rejected状态,最终都会执行代码
  • finally方法不接收参数,因为无论前面试fulfilled状态还是reject的状态,他都会执行
const promise = new Promise((resolve, reject) => {
    // resolve("成功")
    reject("拒绝")
})
promise.then(res => {
    console.log(res)
}).catch((err) => {
    console.log(err)//执行
}).finally(() => {
    console.log("finally函数")//执行
})

resolve方法

then、catch、finally方法都属于Promise的实例方法,都是存放在Promise的Prototype上

resolve是一个类方法

参数形态

  • 普通的值或者对象
  • 本身是Promise
  • 参数是一个对象且有then函数
Promise.resolve("mjy").then(res=>{
    console.log(res)
})
//等价于
new Promise((resolve) => resolve("mjy"))

相当于new Promise,并且执行resolve

reject方法

reject方法类似于类方法resolve,只是会将Promise对象的状态设置为reject状态

Promise.rejec用法相当于new Promise,只是会调用reject

参数形态

  • 无论参数是什么祥泰,都会直接做为reject状态的参数传递到catch
Promise.resolve("mjy").then(res=>{
    console.log(res)
})
//等价于
new Promise((resolve,reject) => reject("mjy"))

相当于new Promise,并且执行reject

All方法

作用:将多个Promise包裹在一起行成一个新的Promise对象;

新的Promise对象状态由包裹的所有Promise对象共同决定:

  • 当所有的对象转态变化才能fulfilled状态时,新的Promise对象状为fulfilled,并且会将所有的Promise的返回值组成一个数组;
  • 当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数;
  • 传入一个可迭代对象

缺陷:dang 一个Promise变成rejected状态是,新的Promise就会立即变成对应的reject转态,

那么对于处于resolved的,以及依然处于pending状态的Promise,我们是获取不到对应结果的

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("成功")
    }, 1000)
})
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("拒绝")//返回 
    }, 2000)
})
const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("成功")
    }, 3000)
})
Promise.all([p1,p2,p3]).then(res => {
    console.log(res)
}).catch((err) => {
    console.log(err)
})
//执行结果 有reject 返回了  拒绝
//无reject 返回了 [ '成功', '成功', '成功' ]

allSettled方法

新增于ES11(ES2020)

  • 该方法会在所有的Promise都有结果(settled),无论是fulfilled还是rejected,才会有最终的状态
  • 这个Promise的结果一定是fulfilled
const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("成功")
    }, 1000)
})
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("拒绝")
    }, 2000)
})
const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("成功")
    }, 3000)
})
Promise.allSettled([p1,p2,p3]).then(res => {
    console.log(res)
}).catch((err) => {
    console.log(err)
})
/*执行结果
[
  { status: 'fulfilled', value: '成功' },
  { status: 'rejected', reason: '拒绝' },
  { status: 'fulfilled', value: '成功' }
]
​
*/

race方法

如果有一个Promise有了结果,我们就希望决定最终新Promise的状态,那么可以使用race方法

表示多个Promise相互竞争,谁先有结果,那么就使用谁得结果,无论fulfilled还是rejected

any方法

  • any方法是ES12中新增的方法

  • any方法会等到一个fulfilled状态,才会决定新Promise的状态

  • 如果所有的Promise都是reject的,那么也会等到所有的Promise都变成rejected状态

    注意:如果所有的Promise都是rejected的,那么会报一个AggregateError错误

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("拒绝")
    }, 1000)
})
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("拒绝")
    }, 2000)
})
const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("拒绝")
    }, 3000)
})
Promise.any([p1,p2,p3]).then(res => {
    console.log(res)
}).catch((err) => {
    console.log(err)
})
/*
运行结果
[AggregateError: All promises were rejected] {
  [errors]: [ '拒绝', '拒绝', '拒绝' ]
}
*/