解析Pronise

59 阅读3分钟

什么是Promise?

Promise 是一种设计模式(1976),前端只是应用了这种设计模式, 而且这种设计模式最初是后端, 而前端借鉴来的;

  • Promise 是异步编程的一种解决方案:
  • 从语法上讲,promise是一个对象,从它可以获取异步操的消息;
  • 从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
  • promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);
  • 状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

Promise 的作用

Promise的出现是解决前端异步操作的问题, 在没有 Promise 之前, 可能大部分的时候使用回调的方式来处理异步操作, 并且对于 成功或者失败 取名不是很规范,并且容易出现回调地狱

回调地狱举例
getUser( user =>{
 getGroups(user,(groups)=>{
  groups.forEach( (g)=>{
   g.filter(x => x.ownerId === user.id)
    .forEach(x => console.log(x))
  })
 }) 
})
在某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称-回调地狱。

这时候Promise就出现了

promise是用来解决三个问题的:

  1. 规范回调的名称或顺序
  2. 拒绝回调地狱,让代码可读性更强
  3. 方便捕获错误

# Promise、Promise.all、Promise.race的用法

Promise初体验

//生成随机数
function rand(m,n){
   return Math.ceil(Math.random() * (n-m+1)) + m-1;
}
//点击按钮, 1s 后显示是否中奖(30%概率中奖)若中奖弹出恭喜恭喜,奖品为 10万 RMB 劳斯莱斯优惠券若未中奖弹出 再接再厉

// Promise 形式实现
// resolve 解决 函数类型的数据   reject 拒绝函数类型的数据
const p = new Promise((resolve, reject) => {
  setTimeout(() => {
  //30%几率成功 1~30设为成功
  //获取从1 - 100的一个随机数
  let n = rand(1, 100);
  //判断
  if(n <= 30){
     resolve(n); // 将 promise 对象的状态设置为 [成功]
  }else(
     reject(n); // 将 promise 对象的状态设置为 [失败]
},1000);

//调用 then 方法
//value  本身为值的意思
//reason 本身为理由的意思 (可随意写)
p.then(
  (value) => {alert('恭喜恭喜,奖品为 10万 RMB 劳斯莱斯优惠券' + value)}, 
  (reason) => {alert('再接再厉' + reason)}
)

这里 Promise 的使用就很简单, new Promise((resolve, reject) => {}), 四个单词, Promise在这里就声明了 成功是 resolve, 失败是reject, 统一了规范, 而且可以获取异步任务当中成功和失败的结果值

Promise.all使用

Promise.all 需要传入一个数组,数组中的元素都是 Promise 对象。
当这些对象都执行成功时,则 all 对应的 promise 也成功,且执行 then 中的成功回调。
如果有一个失败了,则 all 对应的 promise 失败,且失败时只能获得第一个失败 Promise 的数据。

const p1 = new Promise((resolve, reject) => { resolve('成功了') }) 
const p2 = Promise.resolve('success') 
const p3 = Promise.reject('失败') 

Promise.all([p1, p2])
  .then((result) => {
    console.log(result) //[ "成功了", "success"] 
  })
  .catch((error) => {
    //未被调用 
  }) 
 
Promise.all([p1, p3, p2])
   .then((result) => {
     //未被调用 
   })
   .catch((error) => {
     console.log(error) //"失败" 
   });

Promise.race使用

Promise.race() 里面哪个 Promise 对象最快得到结果,就返回那个结果,不管结果本身是成功状态还是失败状态。

const p1 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 500, "one");
});
const p2 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, "two");
});
Promise.race([p1, p2]).then((result) => {
  console.log(result); // "two"
  // 两个都完成,但 p2 更快
});


const p3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, "three");
});
const p4 = new Promise(function(resolve, reject) {
  setTimeout(reject, 500, "four");
});
Promise.race([p3, p4]).then((result) => {
  console.log(result); // "three"
  // p3 更快,所以它完成了
}, (error) => {
  // 未被调用
});


const p5 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, "five");
});
const p6 = new Promise(function(resolve, reject) {
    setTimeout(reject, 100, "six");
});
Promise.race([p5, p6]).then((result) => {
  // 未被调用
}, error => {
  console.log(error); // "six"
  // p6 更快,所以它失败了
});