Promise

185 阅读4分钟

异步

Promise

Promise:是一个类(一个构造函数),可以翻译为承诺。 image.png image.png

Promise的三种状态: pending:初始状态,待定。 fulfilled:已敲定/兑现 rejected:已拒绝

状态一旦确定将不再改变,只有两种变换方式:

pending -> fulfilled 代表成功

pending -> rejected 代表失败

image.png

resolve(参数)

  • 1> 普通的值或者对象 直接执行.then方法里面的第一个回调 pending -> fulfilled

  • 2> 传入(参数是)一个Promise

    那么当前的Promise的状态会由传入的Promise来决定,相当于状态进行了移交,如果传入的这个调用resolve就执行第一个回调,如果传入的这个调用reject就执行第二个回调

  • 3> 传入一个对象, 并且这个对象有实现then方法(并且这个对象是实现了thenable接口),那么也会执行该then方法, 并且由该then方法决定后续状态

image.png Promise 的三个对象方法 then() catch() finally() 都是Promise的实例方法 都是存放在Promise的prototype上的

promise.then(()=>{}) 方法

  1. 同一个Promise可以被多次调用then方法,当我们的resolve方法被回调时, 所有的then方法中的回调函数都会被调用

  2. then方法本身也是有返回值的, 它的返回值是Promise

    • 如果我们返回的是一个普通值(数值/字符串/普通对象/undefined), 那么这个普通的值被作为一个新的Promise的resolve值
    • 如果我们返回的是一个Promise 新的promise将决定下一次then的执行 指的是链式调用
    • 如果返回的是一个对象, 并且该对象实现了thenable ,同时也将决定下一次then的执行 指的是链式调用

promise.catch(()=>{}) 方法

  • 当executor抛出异常时或者reject(), 也是会调用错误(拒绝)捕获的回调函数的 .catch()

  • .catch() 优先捕获传入进来的promise 其次还可以捕获.then返回的promise 特殊 image.png

  • 如果在.then方法里面或者后面没有.失败的回调的话 会报错

    Uncaught (in promise) rejected status image.png

  • .catch也是又返回值的 和then一样会返回一个Promise 如果直接抛出错误将不会再向后执行 promise 微任务

image.png

.finally(()=>{}) 不管promise是调resolve还是调reject 最后finally都会执行 一般用于promise执行完后的善后工作 ,返回的也是一个promise 但是很少在后面在写 记住就是总会执行 上面抛出错误也会执行 不接收任何参数

类方法 .resolve() .reject() .all() .allSetled() .race() .any()

Promise.resolve() 可以将一个值直接转换为promise 并且调用的是resolve

image.png

传入的值也分三种情况 和then的值一样的规律 image.png

reject() 同样也是将传入的值转换为一个Promise 执行里面的reject() 但是特殊的地方就是不管传入什么值都直接.catch 不会向上面那样分为三种情况 传入promise 不会帮我们再调用resolve的回调。

.all()

只有当所有的promise都变为fulfilled 时才会执行.all() 里面的.then回调 (.all()返回的是一个promise) 并且打印顺序就是all里面的书写顺序, 如果有一个为rejected 就会执行.catch 打印相应的回调 如果有多个 就只打印第一个 (正常情况是等所有变为fulfilled状态 才执行 如果一旦中途有rejected状态就会终止)

// 创建多个Promise
 const p1 = new Promise((resolve, reject) => {
   setTimeout(() => {
     resolve(11111)
   }, 1000);
 })
 const p2 = new Promise((resolve, reject) => {
   setTimeout(() => {
     resolve(22222)
   }, 2000);
 })
 const p3 = new Promise((resolve, reject) => {
   setTimeout(() => {
     resolve(33333)
   }, 3000);
 })
 // 需求: 所有的Promise都变成fulfilled时, 再拿到结果
 // 意外: 在拿到所有结果之前, 有一个promise变成了rejected, 那么整个promise是rejected
 Promise.all([p1, p3, p2, "aaaa"]).then(res => {
   console.log(res)   // [11111, 33333, 22222, 'aaaa']
 }).catch(err => {
   console.log("err:", err)
 })

allSetled 和all不同就是等待所有都执行完 返回对应的状态以及值

Promise.allSettled([p3, p1, p2, "aaaa"]).then(res => {
   console.log(res)
 }).catch(err => {
   console.log("err:", err)
 })

image.png

race()

// race: 竞技/竞赛
谁先有结果就执行谁
Promise.race([p1, p2, p3]).then(res => {
console.log("res:", res)
}).catch(err => {
console.log("err:", err)
})

any() 至少等到一个resolve 如果执行完了都没有哦resolve 那么就执行.catch

 // any方法
 Promise.any([p1, p2, p3]).then(res => {
   console.log("res:", res)
 }).catch(err => {
   console.log("err:", err.errors)
 })