2024年Web前端最全美团经典面试题解析 —— 如何手写一个Promise,Web前端最新面试题及答案

总结

三套“算法宝典”

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

28天读完349页,这份阿里面试通关手册,助我闯进字节跳动

算法刷题LeetCode中文版(为例)

人与人存在很大的不同,我们都拥有各自的目标,在一线城市漂泊的我偶尔也会羡慕在老家踏踏实实开开心心养老的人,但是我深刻知道自己想要的是一年比一年有进步。

最后,我想说的是,无论你现在什么年龄,位于什么城市,拥有什么背景或学历,跟你比较的人永远都是你自己,所以明年的你看看与今年的你是否有差距,不想做咸鱼的人,只能用尽全力去跳跃。祝愿,明年的你会更好!

由于篇幅有限,下篇的面试技术攻克篇只能够展示出部分的面试题,详细完整版以及答案解析,有需要的可以关注

let demo = new Promise((resolve, reject)=>{

console.log(“在座的各位彭于晏,大家好”);

})

因此,当实例化Promise时,构造函数中就要马上调用传入的excutor函数执行,为了防止出错,加入try,catch:

// 此段代码放在Promise方法里

try {

excutor(resolve, reject);

} catch(err) {

reject(err)

}

3. 状态管理

已经是成功态或是失败态不可再更新状态,Promise 规范中规定:当Promise对象已经由pending状态改变为了成功态(resolved)或是失败态(rejected)就不能再次更改状态。

因此我们在更新状态时要判断,如果当前状态是pending(等待态)才可更新。

function resolve(value){

if (self.status === ‘pending’) {

self.value = value; //保存成功结果

self.status = ‘fulfilled’;

}

}

function reject(reason){

if (self.status === ‘pending’) {

self.reason = reason;

self.status = ‘rejected’;

}

}

以上可以看到:

  1. 在resolve和reject函数中分别加入了判断

  2. 只有当前状态是pending才可进行操作

  3. 将成功的结果和失败的原因都保存到对应的属性上。之后将state属性置为更新后的状态

4. then方法完善

当Promise的状态发生了改变,不论是成功或是失败都会调用then方法。所以,then方法的实现也很简单,根据state状态来调用不同的回调函数即可。

Promise.prototype.then = function(onFulfilled, onRejected){

onFulfilled = typeof onFulfilled === ‘function’ ?

onFulfilled : function (data) { resolve(data) }

onRejected = typeof onRejected === ‘function’ ?

onRejected : function (err) { throw err }

}

代码写到这里似乎基本功能都实现了,可是还有一个很大的问题:目前此Promise还不支持异步代码,如果Promise中封装的是异步操作,then方法无能为力,例:

let demo = new Promise((resolve, reject)=>{

console.log(“在座的各位彭于晏大家好”);

setTimeout(()=>{

resolve(1);

}, 500)

})

// 没有打印

demo.then(data => console.log(data));

第一步是正常打印的,但是 setTimeout 里面的代码不会执行,最后一行也不会打印 “1”。

问题所在:原因是 setTimeout 函数使得 resolve 是异步执行的,有延迟,当调用then方法的时候,此时此刻的状态还是等待态(pending),因此then方法即没有调用 onFulfilled 也没有调用 onRejected。

5. 发布订阅模式登场

这个问题如何解决?我们可以参照发布订阅模式,在执行 then 方法时如果还在等待态(pending),就把回调函数临时寄存到一个数组里,当状态发生改变时依次从数组中取出执行就好,是不是很Nice!

清楚这个思路我们开始实现它,首先在类上新增两个Array类型的数组,用于存放回调函数:

function Promise(excutor){

// 其它代码略

self.onFulfilledCallbacks = [];

self.onRejectedCallbacks = [];

}

在then方法里添加进去:

Promise.prototype.then = function(onFulfilled, onRejected){

// 其它代码略

let self = this;

if(self.status === “pending”){

self.onFulfilledCallbacks.push(onFulfilled);

self.onRejectedCallbacks.push(onRejected);

}

}

在resolve() 与reject() 里逐一遍历:

function resolve(value){

if (self.status === ‘pending’) {

// 其它代码略

self.onFulfilledCallbacks.forEach(item => item(value));

}

}

function reject(reason){

if (self.status === ‘pending’) {

// 其它代码略

self.onRejectedCallbacks.forEach(item => item(reason));

}

}

到这一步,异步也搞定了!再是如何实现链式调用。

6. 经典的链式调用实现

then方法接收的两个函数中,可以通过return把值传给下一个步,也可以返回一个新的Promise把值传给下一步,then方法执行的时候有个特点:

为了保证链式调用,上一次then中不管你是成功还是失败都会把参数作为下一个then中成功时回调的参数

话不多说,开干(只需要再new一个Promise即可):

Promise.prototype.then = function(onFulfilled, onRejected){

onFulfilled = typeof onFulfilled === ‘function’ ?

onFulfilled : function (data) { resolve(data) }

onRejected = typeof onRejected === ‘function’ ?

onRejected : function (err) { throw err }

let self = this;

JavaScript

  • js的基本类型有哪些?引用类型有哪些?null和undefined的区别。

  • 如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

  • Object是引用类型嘛?引用类型和基本类型有什么区别?哪个是存在堆哪一个是存在栈上面的?

  • JS常见的dom操作api

  • 解释一下事件冒泡和事件捕获

  • 事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何组织默认事件?

  • 对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?

  • this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?

  • call,apply,bind

  • 显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

  • 创建对象的多种方式

  • 实现继承的多种方式和优缺点

  • new 一个对象具体做了什么

  • 手写Ajax,XMLHttpRequest

  • 变量提升

  • 举例说明一个匿名函数的典型用例

  • 指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?

  • attribute和property的区别

  • document load和document DOMContentLoaded两个事件的区别

  • JS代码调试

  • 开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值