关注「松宝写代码」,精选好文,每日一题

加入我们一起学习,day day up

作者:saucxs | songEagle

来源:原创

一、前言

2020.12.23日刚立的flag,每日一题,题目类型不限制,可以是:算法题,面试题,阐述题等等。

往期「每日一题」:

接下来是第3道:谈谈你对 promise 的理解?

二、谈谈你对 promise 的理解?

1、我们简单概括一下promise

Promise 是 ES6 新增的语法,解决了回调地狱的问题。

无论是ES6的Promise也好,jQuery的Promise也好,不同的库有不同的实现,但是大家遵循的都是同一套规范,所以,Promise并不指特定的某个实现,它是一种规范,是一套处理JavaScript异步的机制。

Promise 本质上就是一个绑定了回调的对象,而不是将回调传回函数内部。

所以,Promise在一定程度上解决了回调函数的书写结构问题,但回调函数依然在主流程上存在,只不过都放到了then(...)里面,和我们大脑顺序线性的思维逻辑还是有出入的。

2、我们说一下promise相关规范

  • 可以把 Promise 看成一个状态机。初始是 pending 状态,可以通过函数 resolve 和 reject ,将状态转变为 resolved 或者 rejected 状态,状态一旦改变就不能再次变化。

  • then 函数会返回一个 Promise 实例,并且该返回值是一个新的实例而不是之前的实例。因为 Promise 规范规定除了 pending 状态,其他状态是不可以改变的,如果返回的是一个相同实例的话,多个 then 调用就失去意义了。

  • then 方法可以被同一个 promise 调用多次。

  • 值穿透

三、promise 是如何实现的?

1、Promise的简单使用

我们通过这种使用构建Promise实现的最初版本

2、Promise的大致框架

大致框架有了,但是Promise状态,resolve函数,reject函数,以及then等回调没有详细处理

3、Promise的链式存储

我们先看一个例子:

每间隔1秒打印一个数字,哈哈,这个不是真实的间隔1秒,汪汪,

这个的输出是啥?

打印顺序:1、2、3

这里我们能确认的是:

  • 让a,b,c的只能在then的回调接收到
  • 在连续的异步调用中,如何保证异步函数的执行顺序

Promise一个常见的需求就是连续执行两个或者多个异步操作,这种情况下,每一个后来的操作都在前面的操作执行成功之后,带着上一步操作所返回的结果开始执行。这里用setTimeout来处理.

4、Promise的状态机制和执行顺序

为了保证Promise的异步操作时的顺序执行,这里给Promise加上状态机制

5、Promise的递归执行

每个Promise后面链接一个对象,该对象包含onresolved,onrejected,子promise三个属性.

当父Promise 状态改变完毕,执行完相应的onresolved/onrejected的时候,拿到子promise,在等待这个子promise状态改变,在执行相应的onresolved/onrejected。依次循环直到当前promise没有子promise。

6、Promise的异常处理

每个Promise后面链接一个对象,该对象包含onresolved,onrejected,子promise三个属性.

当父Promise 状态改变完毕,执行完相应的onresolved/onrejected的时候,拿到子promise,在等待这个子promise状态改变,在执行相应的onresolved/onrejected。依次循环直到当前promise没有子promise。

7、Promise的then的实现

then 方法是 Promise 的核心,这里做一下详细介绍。

promise.then(onFulfilled, onRejected)

一个 Promise 的then接受两个参数: onFulfilled和onRejected(都是可选参数,并且为函数,若不是函数将被忽略)

  • onFulfilled 特性:

当 Promise 执行结束后其必须被调用,其第一个参数为 promise 的终值,也就是 resolve 传过来的值

在 Promise 执行结束前不可被调用

其调用次数不可超过一次

  • onRejected 特性

当 Promise 被拒绝执行后其必须被调用,第一个参数为 Promise 的拒绝原因,也就是reject传过来的值

在 Promise 执行结束前不可被调用

其调用次数不可超过一次

  • 调用时机

onFulfilled 和 onRejected 只有在执行环境堆栈仅包含平台代码时才可被调用(平台代码指引擎、环境以及 promise 的实施代码)

  • 调用要求

onFulfilled 和 onRejected 必须被作为函数调用(即没有 this 值,在 严格模式(strict) 中,函数 this 的值为 undefined ;在非严格模式中其为全局对象。)

  • 多次调用

then 方法可以被同一个 promise 调用多次

当 promise 成功执行时,所有 onFulfilled 需按照其注册顺序依次回调

当 promise 被拒绝执行时,所有的 onRejected 需按照其注册顺序依次回调

  • 返回

then方法会返回一个Promise,关于这一点,Promise/A+标准并没有要求返回的这个Promise是一个新的对象,但在Promise/A标准中,明确规定了then要返回一个新的对象,目前的Promise实现中then几乎都是返回一个新的Promise(详情)对象,所以在我们的实现中,也让then返回一个新的Promise对象。

promise2 = promise1.then(onFulfilled, onRejected);
  • 如果 onFulfilled 或者 onRejected 返回一个值 x ,则运行下面的 Promise 解决过程:[[Resolve]](promise2, x)
  • 如果 onFulfilled 或者 onRejected 抛出一个异常 e ,则 promise2 必须拒绝执行,并返回拒因 e
  • 如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值
  • 如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的拒因

不论 promise1 被 reject 还是被 resolve , promise2 都会被 resolve,只有出现异常时才会被 rejected。

每个Promise对象都可以在其上多次调用then方法,而每次调用then返回的Promise的状态取决于那一次调用then时传入参数的返回值,所以then不能返回this,因为then每次返回的Promise的结果都有可能不同。

8、Promise的值穿透

我们来看一下这个题的输出:

最终打结果是1而不是2.

我们再来看一下这个题的输出:

各种福利

「松宝写代码」公众号:开发知识体系构建,技术分享,项目实战,实验室,每日一题,带你一起学习新技术,总结学习过程,让你进阶到高级资深工程师,学习项目管理,思考职业发展,生活感悟,充实中成长起来。问题或建议,请公众号留言。

1、字节内推福利

回复「校招」获取内推码

回复「社招」获取内推

回复「实习生」获取内推

后续会有更多福利

2、学习资料福利

回复「算法」获取算法学习资料

3、每日一题

「每日一题」面试官问你对Promise的理解?可能是需要你能手动实现各个特性的更多相关文章

  1. 「每日一题」有人上次在dy面试,面试官问我:vue数据绑定的实现原理。你说我该如何回答?

    关注「松宝写代码」,精选好文,每日一题 ​时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 来源:原创 一.前言 文章首发在「松宝写代码」 2020. ...

  2. 「干货」面试官问我如何快速搜索10万个矩形?——我说RBush

    「干货」面试官问我如何快速搜索10万个矩形?--我说RBUSH 前言 亲爱的coder们,我又来了,一个喜欢图形的程序员‍,前几篇文章一直都在教大家怎么画地图.画折线图.画烟花,难道图形就是这样嘛,当 ...

  3. [每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?

    关注「松宝写代码」,精选好文,每日一题 ​时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  4. [每日一题]面试官问:for in和for of 的区别和原理?

    关注「松宝写代码」,精选好文,每日一题 ​时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  5. [每日一题]面试官问:谈谈你对ES6的proxy的理解?

    [每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  6. 面试官问我JVM调优,我忍不住了!

    面试官:今天要不来聊聊JVM调优相关的吧? 面试官:你曾经在生产环境下有过调优JVM的经历吗? 候选者:没有 面试官:... 候选者:嗯...是这样的,我们一般优化系统的思路是这样的 候选者:1. 一 ...

  7. 每日一问:面试结束时面试官问"你有什么问题需要问我呢",该如何回答?

    面试结束时面试官问"你有什么问题需要问我呢",该如何回答?

  8. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...

  9. 当阿里面试官问我:Java创建线程有几种方式?我就知道问题没那么简单

    这是最新的大厂面试系列,还原真实场景,提炼出知识点分享给大家. 点赞再看,养成习惯~ 微信搜索[武哥聊编程],关注这个 Java 菜鸟. 昨天有个小伙伴去阿里面试实习生岗位,面试官问他了一个老生常谈的 ...

随机推荐

  1. ModelViewSet + ModelSerializer

     ModelSerializer (封装好的序列化器,不需要我们写字段) from rest_framework import serializers from .models import * cl ...

  2. java面试复习重点:类的管理及常用工具,教你抓住面试的重点!

    java复习: 类的管理及常用工具类 包 写在程序文件的第一行 一个Java 源文件中只能声明一个包, 且声明语句只能作为源文件的第一条指令 导入类能导入非public类,但是不能用因为在其他包缺省的 ...

  3. 基础篇:JAVA.Stream函数,优雅的数据流操作

    前言 平时操作集合数据,我们一般都是for或者iterator去遍历,不是很好看.java提供了Stream的概念,它可以让我们把集合数据当做一个个元素在处理,并且提供多线程模式 流的创建 流的各种数 ...

  4. MDX非常规百分比算法-过滤数据后的百分比

    网上有很多关于占比的帖子,基本上都是按照层次结构来做的,比如某个子项占总体的百分比(\all).某个子项占父项的百分比(\parent).某个子项占其祖先的百分比(\ancestor)....等等,如 ...

  5. Object.prototype.toString.call()为什么可以用来检测数据类型?

    obj.toString()方法是用来干什么的 每一个对象都有一个toString()方法,默认情况下toString()被每一个Object对象继承,如果此方法未被重写,toString()返回&q ...

  6. Jmeter添加事务

    事务 通过第三方工具或jmeter代理录制的脚本,你会发现会录制很多的子请求.比如当打开首页后, 会继续打开图片,css,其他请求等资源文件. 通常我们会剔除掉这些子请求, 但如果我需要衡量打开一个页 ...

  7. Python 常用方法和模块的使用(time & datetime & os &random &sys &shutil)-(六)

    1 比较常用的一些方法 1.eval()方法:执行字符串表达式,并返回到字符串. 2.序列化:变量从内存中变成可存储或传输到文件或变量的过程,可以保存当时对象的状态,实现其生命周期的延长,并且需要时可 ...

  8. Java基础学习之HelloWorld(2)

    前言 学习一门新的编程语言永远逃脱不了一场Hello World. 1.第一个程序 1.1.磁盘中新建一个文件 这里我们需要将文件后缀名显示出来,就是文件格式. 打开控制面板,取消隐藏已知文件类型的扩 ...

  9. Scrum 冲刺 第二篇

    Scrum 冲刺 第二篇 每日会议照片 昨天已完成工作 队员 昨日完成任务 黄梓浩 初步完成app项目架构搭建 黄清山 完成部分个人界面模块数据库的接口 邓富荣 完成部分后台首页模块数据库的接口 钟俊 ...

  10. javascript常用继承方式.

      //原型链继承 function Parent() { this.name = 'per'; } function Child() { this.age = 20; } Child.prototy ...