Js手写面试题5-Promise

Promise

❓有任何疑问都可以私信我解答

⚡仓库地址:https://gitee.com/super_li_yu/promise

😛建议关注,持续更新。

✒️主要内容:Promise

Promise是一门是在ES6里提出的新技术,是JS在异步编程的一种解决方案,可以支持链式调用,可以解决地狱问题指定回调的问题更加灵活。

Promise成功会调用resovle中,失败会调用reject。then里面会包裹两个函数体,第一个函数体放成功的逻辑,第二个函数体放失败的逻辑。

1.原理

1.Promise的状态

  • pending 进行中
  • resolved/fullfilled 成功
  • rejected 失败

2.Promise 对象的值

实例对象中的另外一个属性:[PromiseResult]

保存着对象[成功/失败]的结果

  • resolve
  • reject

3.Promise的工作流程

promise的执行流程

4.Promise相关的API

  1. Promise构造函数:Promise(excutor){}
    • excutor函数:执行器。(resolve,reject)=>{}
    • resolve函数:内部定义成功时我们调用的函数value=>{}
    • reject函数:内部定义的失败时候会调用函数reson=>{}

说明

excutor会在Promise内部立即同步调用,异步操作在执行器中执行。

  1. Promise.prototype.then方法:(onResolved,onRejected)=>{}
    • onResolved函数:成功的回调函数(value)=>{}
    • onReject函数:失败的回调(reson)=>{}

说明

指定用于得到成功的value的成功回调和用于得到失败的reson的失败回调返回一个新的Promise对象

  1. Promise.prototype.catch方法:(onRejected)=>{}
    • onRejected函数:失败的回调函数(reson)=>{}
  2. Promise.resolve方法:(value)=>{}
    • value成功的数据或者promise对象

说明

返回一个成功/失败的Promise对象

1.如果传入的的参数为非promise类型的对象,则返回的结果为成功promise对象

2.如果传入的参数为promise对象,则参数的结果决定了resolve的结果

  1. Promise.reject方法:(reson)=>{}
    • reson:失败的原因

说明

返回一个失败的Promise对象

无论你传入什么数值,都是失败的对象

  1. Promise.all方法:(Promise)=>{}
    • Promise:包含n个Promise对象的数组

说明

返回一个新的Promise,只有所有的Promise都成功才成功,只要有一个失败就直接失败

  • 如果都成功,就返回一个数组,里面是返回成功的对象.

  • 如果有一个失败,就返回该失败的结果.

  1. Promise.race方法:(Promises)=>{}
    • promise:包含多个

说明

返回一个新的Promise,第一个完成的Promise的结果状态就是最终的结果状态

2.问题

1.Promise状态的改变

promise的状态改变

2.改变Promise状态和指定回调函数谁先谁后?

then方法先执行还是改变状态先执行.

  1. 都有可能正常情况下是先指定回调再改变状态,但也可以先改变状态再指定回调
  2. 如何先改变状态再指定回调?
    • 再执行器中直接调用resolev()/reject()
    • 延迟更长时间才调用then()
  3. 什么时候才能得到数据?
    • 如果先指定回调,那当状态发生改变时,回调函数就会调用,得到数据.
    • 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据.
  4. promise.then()返回的新promise的结果状态由什么决定?
    • 简单表达:由then()指定的回调函数执行的结果决定
    • 如果返回的是非promise的任意值,新promise变成

3.Promise的异常穿透

  1. 当使用Promise的then链式调用后,可以在最后指定失败的回调
  2. 当前任何操作出现了异常,都会传到最后失败的回调中处理

这块应用场景最多的还是在链式调用的最后,使用.catch来捕捉错误.中间出现的任何错误,都可以到最后进行捕获

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    // resolve('ok');
    reject('出错了')
  }, 1000)
})


p.then(value => {
  console.log(111);
}).then(value => {
  console.log(222);  //success
}).then(value => {
  console.log(333); //undefined
}).catch(reson => {
  console.warn(reson);
})

4.如何中断Promise链条

只要我们给消息队列中想要中断的位置添加一个状态为pedding(进行中)的Promise就可以了。

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('ok')
  }, 1000)
});

p.then(value => {
  console.log(111)
  //返回一个padding状态的promise的回调对象
  return new Promise(() => { })
}).then(value => {
  console.log(222);
}).then(value => {
  console.log(333);
}).catch(reson => {
  console.log(reson);
})

这样控制台只会输出111,后面的222,333,就不会再输出了。

5.手写一个promise

这块内容在代码仓库里哦

代码

抽奖函数

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>抽奖系统</title>
</head>
<body>
  <button id="btn">点击抽奖</button>
</body>
</html>


<script>
  //生成随机函数
  function rand(m,n){
    return Math.ceil(Math.random() * (n-m+1)) + m-1;
  }

  /**
   * 点击按钮,2s后显示是否中奖(30%概率)
   * 中奖弹出
   * 未中奖弹出  再次努力
  */

  //原生js实现
//  const btn = document.querySelector("#btn");
//   btn.addEventListener('click',function(){
//     //定时器
//     setTimeout(()=>{
//       //30%  1-100   1-30
//       let n = rand(1,100)
//       if(n <= 30){
//         alert('中奖')
//       }else{
//         alert('没中奖')
//       }
//     },1000)
//   })




// Promise实现
/**
 * resolve 解决  函数类型的数据
 * rejet 拒绝    函数类型的数据
*/
const btn = document.querySelector("#btn");
btn.addEventListener('click',function(){
  const p = new Promise((resove,reject)=>{
  setTimeout(()=>{
  //30%  1-100   1-30
  let n = rand(1,100)
  if(n <= 30){
    resove(n); //调用完成后,可以将Promise对象的状态设置为成功
  }else{
    reject(n); //调用完成后,可以将Promise对象的状态设置为失败
  }
  },1000)
})

//调用then方法
p.then((n)=>{
  alert(`中奖号为${n}`);
},(n)=>{
  alert(`失败,号码为${n}`);
})
});


</script>

其他源码看仓库即可

posted @ 2022-09-28 22:38  抗争的小青年  阅读(90)  评论(0编辑  收藏  举报