当前位置: 首页 > news >正文

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的工作流程

请添加图片描述

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状态的改变

请添加图片描述

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>

其他源码看仓库即可

相关文章:

  • T1094 与7无关的数(信息学一本通C++)
  • MySQL高可用之MHA集群
  • Hive数据类型、部分函数及关键字整理
  • Python采集某Top 250信息,再也不怕寂寞无聊......
  • 【XGBoost】第 2 章:深度决策树
  • 如何在Linux服务器上部署Vue项目
  • 基于 velero 工具迁移 kubesphere 后端存储
  • SAP PI PO 接口常见问题处理:队列平衡的统计平均分配
  • Vue学习之旅——开发准备
  • 【Unity小功能开发实战教程】重写MaskableGraphic实现UI图片圆角化功能
  • drools动态规则之Maven解析
  • 【收藏系列】多线程八股文总结
  • [Typescript]基础篇之接口
  • 现学现用的 10 个 Python 技巧
  • 3 UI开发的点点滴滴
  • JavaScript 如何正确处理 Unicode 编码问题!
  • 【RocksDB】TransactionDB源码分析
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • Docker: 容器互访的三种方式
  • es6(二):字符串的扩展
  • javascript 总结(常用工具类的封装)
  • k8s如何管理Pod
  • laravel 用artisan创建自己的模板
  • php面试题 汇集2
  • Redis 中的布隆过滤器
  • 初识 beanstalkd
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 力扣(LeetCode)22
  • 普通函数和构造函数的区别
  • 三栏布局总结
  • 深入浅出webpack学习(1)--核心概念
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 通过git安装npm私有模块
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #pragam once 和 #ifndef 预编译头
  • #QT(串口助手-界面)
  • #微信小程序(布局、渲染层基础知识)
  • $jQuery 重写Alert样式方法
  • (007)XHTML文档之标题——h1~h6
  • (BFS)hdoj2377-Bus Pass
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (四)JPA - JQPL 实现增删改查
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET Core 和 .NET Framework 中的 MEF2
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .NET框架