面试官对不起!我终于会了Promise…(一面凉经泪目)

释放双眼,带上耳机,听听看~!

文章目录[隐藏]

前言

在下前端小白菜也想找到实习来着,于是乎就面了面。先来给所有的问题给大家分享吧。

面试题

  • CSS 实现水平垂直居中
  • flex的属性
  • CSS transition的实现效果和有哪些属性
  • CSS 实现沿Y轴旋转360度 (直接自爆了 CSS不行….麻了)
  • 好,那来点JS 基本数据类型有哪些  用什么判断
  • 数组怎么判断
  • 引用类型和基本类型的区别
  • 什么是栈?什么是堆?
  • 手写 翻转字符串
  • 手写 Sum(1,2,3)的累加(argument)(我以为是柯里化,面试官笑了一下,脑筋不要这么死嘛)
  • 箭头函数和普通函数的区别(上题忘记了argument,面试官特意问这个问题提醒我,奈何基础太差救不起来了…泪目)
  • 数组去重的方法
  • 图片懒加载
  • 跨域产生的原因,同源策略是什么
  • 说说你了解的解决办法(只说了JSONP和CORS)
  • Cookie、sessionStorage、localStorage的区别
  • get 和 post 的区别 (只说了传参方式和功能不同,面试官问还有吗 其他的不知道了…)
  • 问了一下项目,react
  • 对ES6的了解 (Promise果真逃不了….)
  • let var const的区别
  • 知道Promise嘛?聊聊对Promise的理解?(说了一下Promise对象代表一个异步操作,有三种状态,状态转变为单向…)
  • 那它是为了解决什么问题的?(emmm当异步返回值又需要等待另一个异步就会嵌套回调,Promise可以解决这个回调地狱问题)
  • 那它是如何解决回调地狱的?(Promise对象内部是同步的,内部得到内部值后进行调用.then的异步操作,可以一直.then .then …)
  • 好,你说可以一直.then .then …那它是如何实现一直.then 的?(emmm… 这个.then链式调用就是…额这个…)
  • Promise有哪些方法 all和race区别是什么
  • 具体说一下 .catch() 和 reject  (…我人麻了…)

结束环节

  • 问了面试官对CSS的理解(必须但非重要,前端的核心还是尽量一比一还原设计稿,只有写好了页面才能考虑交互)
  • 如何学习(基础是最重要的,CSS和JS要注重实践,盖房子最重要的还是地基,所有的框架源码,组件等都基于CSS和JS)
  • 曾经是如何度过这个过程的(多做项目,在项目中学习理解每个细节,再次告诫我基础的重要性)

Promise概述

Promise是ES6新增的引用类型,可以通过new来进行实例化对象。Promise内部包含着异步的操作。

new Promise(fn)

Promise.resolve(fn)

这两种方式都会返回一个 Promise 对象。

  • Promise 有三种状态:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected),且Promise 必须为三种状态之一只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
  • 状态只能由 Pending 变为 Fulfilled 或由 Pending 变为 Rejected ,且状态改变之后不会在发生变化,会一直保持这个状态。
  • Pending 变为 Fulfilled 会得到一个私有value,Pending 变为 Rejected会得到一个私有reason,当Promise达到了Fulfilled或Rejected时,执行的异步代码会接收到这个value或reason。

知道了这些,我们可以得到下面的代码:

实现原理

基本用法

Promise状态只能在内部进行操作,内部操作在Promise执行器函数执行。Promise必须接受一个函数作为参数,我们称该函数为执行器函数,执行器函数又包含resolve和reject两个参数,它们是两个函数。

  • resolve : 将Promise对象的状态从 Pending(进行中) 变为 Fulfilled(已成功)
  • reject : 将Promise对象的状态从 Pending(进行中) 变为 Rejected(已失败),并抛出错误。

 

使用栗子

实现原理

  • p1 resolve为成功,接收参数value,状态改变为fulfilled,不可再次改变。
  • p2 reject为失败,接收参数reason,状态改变为rejected,不可再次改变。
  • 如果executor执行器函数执行报错,直接执行reject。

所以得到如下代码:

检验一下上述代码咯:

  • 当执行代码1时输出为 0 后一秒输出 10 和 fulfilled 状态被执行
  • 当执行代码2时输出为 0 后一秒输出 我不爱你了 和 rejected 状态被执行
  • 当执行代码3时 抛出错误 是你的错

.then方法

promise.then(onFulfilled, onRejected)

  • 初始化Promise时,执行器函数已经改变了Promise的状态。且执行器函数是同步执行的。异步操作返回的数据(成功的值和失败的原因)可以交给.then处理,为Promise实例提供处理程序。
  • Promise实例生成以后,可以用then方法分别指定resolved状态rejected状态的回调函数。这两个函数onFulfilled,onRejected都是可选的,不一定要提供。如果提供,则会Promise分别进入resolved状态rejected状态时执行。
  • 而且任何传给then方法的非函数类型参数都会被静默忽略。
  • then 方法必须返回一个新的 promise 对象(实现链式调用的关键)

实现原理

  • Promise只能转换最终状态一次,所以onFulfilledonRejected两个参数的操作是互斥
  • 当状态state为fulfilled,则执行onFulfilled,传入this.value。当状态state为rejected,则执行onRejected,传入this.reason

当resolve在setTomeout内执行,then时state还是pending等待状态 我们就需要在then调用的时候,将成功和失败存到各自的数组,一旦reject或者resolve,就调用它们。

现可以异步实现了,但是还是不能链式调用啊?为保证 then 函数链式调用,then 需要返回 promise 实例,再把这个promise返回的值传入下一个then中。

链式调用及后续实现源码

这部分我也不会,还没看懂。后续再更。先贴代码:

有兴趣的小伙伴可移步

参考

Promise的各种方法

Promise.prototype.catch()

catch 异常处理函数,处理前面回调中可能抛出的异常。只接收一个参数onRejected处理程序。它相当于调用Promise.prototype.then(null,onRejected),所以它也会返回一个新的Promise

  • 栗子

当第一个.then的异常被捕获后可以继续执行。

Promise.all()

Promise.all()创建的Promise会在这一组Promise全部解决后在解决。也就是说会等待所有的promise程序都返回结果之后执行后续的程序。返回一个新的Promise。

  • 栗子

有上述栗子得到,all的性质:

  • 如果所有都成功,则合成Promise的返回值就是所有子Promise的返回值数组。
  • 如果有一个失败,那么第一个失败的会把自己的理由作为合成Promise的失败理由。

Promise.race()

Promise.race()是一组集合中最先解决或最先拒绝的Promise,返回一个新的Promise。

  • 栗子

有上述栗子得到,race的性质:

  • 无论如何,最先执行完成的,就执行相应后面的.then或者.catch。谁先以谁作为回调

总结

上面的Promise就总结到这里,讲的可能不太清楚,有兴趣的小伙伴可以看看链接呀,有什么理解也可以在下方评论区一起交流学习。

面试结束了,面试官人很好,聊的很开心,问题大概都能说上来一点,却总有关键部分忘了hhhhhh,结尾跟面试官聊了一下容易忘这个问题,哈哈哈哈他说我忘就是没学会,以后还是要多总结,多做项目…

面试可以让自己发现更多的知识盲点,从而促进自己学习,大家一起加油冲呀!!

给TA买糖
共{{data.count}}人
人已赞赏
前端技术

可能是最好的 this 解析了...

2021-12-22 21:12:33

前端技术

2021 年 JS 烧脑面试题(20多道具有一定迷惑性的js题)

2021-12-22 21:20:10

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索