Promise的使用详解与细节分析

目录

一、promise的基本使用

1.应用场景:

2.executor

3.Promise的三种状态

二、Promise的resolve参数

三、Promise的对象方法(实例方法)

1.then方法

2.catch方法

四、Promise的类方法

1.reslove类方法

3. all类方法

4. allSettled类方法

5. race类方法

6. any类方法


一、promise的基本使用

1.应用场景:

Promise是一个类,可以翻译成 承诺、许诺 、期约; 当我们需要给予调用者一个承诺:待会儿我会给你回调数据时,就可以创建一个Promise的对象;

2.executor

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

  • 通常我们会在Executor中确定我们的Promise状态:

    • 通过resolve,可以兑现(fulfilled)Promise的状态,我们也可以称之为已决议(resolved)

    • 通过reject,可以拒绝(reject)Promise的状态;

  • 注意:一旦状态被确定下来,Promise的状态会被 锁死,该Promise的状态是不可更改的

    • 在我们调用resolve的时候,如果resolve传入的值本身不是一个Promise,那么会将该Promise的状态变成 兑 现(fulfilled)

    • 在之后我们去调用reject时,已经不会有任何的响应了(并不是这行代码不会执行,而是无法改变Promise状 态);

3.Promise的三种状态

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

    • 当执行executor中的代码时,处于该状态;

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

    • 执行了resolve时,处于该状态;

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

    • 执行了reject时,处于该状态;

代码示例:

// 注意:Promise状态一旦被确定下来 就不可以更改
new Promise((resolve, reject) => {
  // pending状态 初始状态,既没有被兑现,也没有被拒绝
  console.log("---------------");
  // fulfilled状态 已兑现,意味着操作成功完成
  // resolve()
  // rejected状态 意味着操作失败
}).then(res => {
  console.log(res);
}, err => {
  console.log(err);
})

二、Promise的resolve参数

区别:

  • 情况一:如果resolve传入一个普通的值或者对象,那么这个值会作为then回调的参数;

  • 情况二:如果resolve中传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态:

  • 情况三:如果resolve中传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,并且根据 then方法的结果来决定Promise的状态

代码示例:

/**
 * resolve参数
 * 1> 普通的值或对象 pending -> fulfilled
 * 2> 传入一个Promise
 *    那么当前Promise的状态会由传入的Promise来决定
 *    相当于状态进行了移交
 * 3> 传入一个对象,并且这个对象有实现then的方法(并且这个对象是实现了thenable接口)
 *    那么也会执行该then方法,并且又该then方法决定后续状态
 */
// 一个新的Promise对象
const newPromise = new Promise((resolve, reject) => {
  // resolve("bbbb")
  // reject("err")
})

new Promise((resolve,reject) => {
  // 1.普通的值或对象
  resolve("aaaa")
  // resolve({name: 'kk'})
  // 2.传入一个Promise
  // resolve(newPromise)
  // 3.传入一个对象,并且这个对象有实现then的方法
  // const obj = {
  //   then: function(resolve, reject) {
  //     resolve("resolve message")
  //   }
  // }
  // resolve(obj)
}).then(res => {
  console.log("res:", res);
}, err => {
  console.log("err:", err);
})

三、Promise的对象方法(实例方法)

1.then方法

then方法是Promise对象上的一个方法:它其实是放在Promise的原型上的 Promise.prototype.then

1.2 then可以被多次调用

一个Promise的then方法是可以被多次调用的:

  • 每次调用我们都可以传入对应的fulfilled回调;

  • 当Promise的状态变成fulfilled的时候,这些回调函数都会被执行;

代码示例:

// then方法可以被多次调用
// 当Promise的状态变成fulfilled的时候,这些回调函数都会被执行
const promise = new Promise((reslove, reject) => {
  reslove('111111')
})
promise.then(res => {
  console.log(res);
})
promise.then(res => {
  console.log(res);
})
promise.then(res => {
  console.log(res);
})

1.3 then方法的返回值

then传入的回调函数可以有返回值(它的返回值是一个新的Promise对象)

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

三种情况:

如果我们的返回值是一个普通值(数值/字符串/普通对象/undefined),那么这个普通的值被作为一个新的Promise的resolve值

const promise = new Promise((resolve, reject) => {
  resolve()
})
promise.then(() => {
  return 'aaaaa' //这里会返回一个新的Promise对象 Promise((resolve,reject) => { resolve('aaaaa') })
}).then(res => {
  console.log('res:', res);
})

如果返回一个Promise

promise.then(res => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('11111')
    },3000)
  }) // 返回一个新的Promise对象 Promise((resolve, reject) => { resolve(new Promise) }) 于是resolve(Promise)里面的Promise的reslove决定了外面的res输出值
        
}).then(res => {
  console.log("res:", res);
})

如果返回的是一个对象 并且该对象实现了thenable

promise.then(res => {
  return {
    then: function(resolve, reject) {
      resolve(22222)
    }
  }
}).then(res => {
  console.log("res:", res);
})

2.catch方法

2.1 基本使用

catch会查看promise是否是rejected状态,是就返回,否则,查看then方法是否返回一个新的promise对象,且新的promise对象是rejected状态

const promise = new Promise((resolve, reject) => {
  resolve()
  // reject("reject status")
  // throw new Error("rejected status")
})
// 1.当executor抛出异常时也是会调错误(拒绝)捕获回调函数的
promise.then(undefined, err => {
  console.log("err:", err);
})

// 2.通过catch方法来传入错误(拒绝)捕获回调函数
promise.catch(err => {
  console.log("err:", err);
})

promise.then(res => {
  // return new Promise((resolve, reject) => {
  //   reject("then rejected status")
  // })
  throw new Error("error message")
}).catch(err => {
  console.log("err:", err); // err: reject status 这里的catch是外面第一个promise的方法 调用外面的reject
                            // 如果外面的promise没有没有异常,而then返回的promise有异常 catch也会帮助找到这个promise异常 然后输出
})

2.2 catch特殊

当promise里没有reject(), catch就会找到下面then返回的promise,找到里面的reject,并打印

const promise = new Promise((resolve, reject) => {
  // reject(111111)
  resolve()
})

promise.then(res => {
  return new Promise((resolve, reject) => {
    reject(222222)
  })
}).catch(err => {
  console.log(err);
})

2.3 catch的返回值

事实上catch方法也是会返回一个Promise对象的,所以catch方法后面我们可以继续调用then方法或者catch方法: 是res打印,这是因为catch传入的回调在执行完后,默认状态依然会是fulfilled的;

const promise = new Promise((resolve, reject) => {
  // reject(111111)
  resolve()
})

promise.then(res => {
  return new Promise((resolve, reject) => {
    reject(222222)
  })
}).catch(err => {
  console.log(err);
  return "catch return value"
}).then(res => {

}).catch(err => {
  
})

3. finally方法

无论Promise对象无论变成fulfilled还是reject状态,最终都会 被执行的代码。且finally方法是不接收参数的,因为无论前面是fulfilled状态,还是reject状态,它都会执行。

代码示例:

const promise = new Promise((resolve, reject) => {
  resolve()
})

promise.then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
}).finally(() => {
  console.log("finally action");
})

四、Promise的类方法

1.reslove类方法

resolve参数的形态:

  • 情况一:参数是一个普通的值或者对象

  • 情况二:参数本身是Promise

  • 情况三:参数是一个thenable

Promise.resolve("zyk").then(res => {
  console.log(res);
})
// 相当于
const promise = new Promise((resolve, reject) => {
  resolve("zyk")
})

promise.then(res => {
  console.log(res);
})

2. reject类方法

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

Promise.reject传入的参数无论是什么形态,都会直接作为reject状态的参数传递到catch的

// 注意:无论传入什么值都是一样的
const promise = Promise.reject(new Promise((reslove, reject) => {reslove(11111)})) // Promise { 11111 } 
promise.then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})
// 相当于
// const promise = new Promise((reslove, reject) => {
//   reslove(11111)
// })
// promise.then(res => {
//   console.log(res);
// }).catch(err => {
//   console.log(err);
// })

3. all类方法

  • 它的作用是将多个Promise包裹在一起形成一个新的Promise;

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

    • 当所有的Promise状态变成fulfilled状态时,新的Promise状态为fulfilled,并且会将所有Promise的返回值 组成一个数组;

    • 当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数;

  • 缺陷 :当有其中一个Promise变成reject状态时,新Promise就会立即变成对应的reject状态。 那么对于resolved的,以及依然处于pending状态的Promise,我们是获取不到对应的结果的;

const p1 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reslove(11111)
  }, 1000)
})

const p2 = new Promise((reslove, reject) => {
  setTimeout(() => {
    // reslove(22222)
    reject("err message")
  }, 2000)
})

const p3 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reslove(33333)
  }, 3000)
})

// 需求:将所有的Promise都变成fulfilled状态,再难道结果
// 意外:在拿到所有结果之前 如果有一个promise变为reject, 那么整个promi都是rejected状态的
// all相当于返回一个新的Promise 然后Promise(reslove(all里面的参数))
Promise.all([p1, p2, p3, "aaaaa"]).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

4. allSettled类方法

该方法会在所有的Promise都有结果(settled),无论是fulfilled,还是reject时,才会有最终的状态,并且这个Promise的结果一定是fulfilled的;

const p1 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reslove(11111)
  }, 1000)
})

const p2 = new Promise((reslove, reject) => {
  setTimeout(() => {
    // reslove(22222)
    reject("err message")
  }, 2000)
})

const p3 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reslove(33333)
  }, 3000)
})

Promise.allSettled([p1, p2, p3]).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})
/**
 * 打印结果
 * [
    { status: 'fulfilled', value: 11111 },
    { status: 'rejected', reason: 'err message' },
    { status: 'fulfilled', value: 33333 }
   ]   
 */

5. race类方法

只要有一个Promise编程fulfilled状态,那么就结束,但是,如果有一个Promise最快变为reject 那么就执行catch

const p1 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reslove(11111)
  }, 1000)
})

const p2 = new Promise((reslove, reject) => {
  setTimeout(() => {
    // reslove(22222)
    reject("err message")
  }, 500)
})

const p3 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reslove(33333)
  }, 3000)
})
// race: 竞赛
// 只要有一个Promise编程fulfilled状态,那么就结束
// 意外:如果有一个Promise最快变为reject 那么就执行catch
Promise.race([p1, p2, p3]).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

6. any类方法

它会等有一个最快的fulfilled状态,然后就返回其Promise的值,如果全部都为reject 他会返回 AggregateError: All promises were rejected

const p1 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reject(11111)
  }, 1000)
})

const p2 = new Promise((reslove, reject) => {
  setTimeout(() => {
    // reslove(22222)
    reject("err message")
  }, 500)
})

const p3 = new Promise((reslove, reject) => {
  setTimeout(() => {
    reject(33333)
  }, 3000)
})

// 他会等有一个最快的fulfilled状态,然后就返回其Promise的值
// 如果全部都为reject 他会返回 AggregateError: All promises were rejected
Promise.any([p1, p2, p3]).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

  • 28
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值