JavaScript面试必考之实现手写Promise
作者:你也向往长安城吗 发布时间:2024-04-16 10:38:49
标签:JavaScript,手写,Promise
Promise手写
Promise作为面试必考题,Promise的手写也是面试官必问的问题,所以对于Promise我们一定要了解透彻
框架
(function(window) {
MyPromise.prototype.then = function (onResolved, onRejected) {}
MyPromise.prototype.catch = function (onRejected) {}
function MyPromise(executor){
function resolve(value){}
function reject(error){}
try{
executor(resolve, reject)
}catch(error){
reject(error)
}
}
window.MyPromise = MyPromise
}(window))
完整代码
(function (window) {
//将.then,.catch方法挂载在MyPromise原型上
MyPromise.prototype.then = function (onResolved, onRejected) {//.then接受两个回调函数,resolved状态和rejeced状态
// .then返回一个promise对象
return new MyPromise((resolve, reject) => {
let self = this;
if (self.status === 'pending') {//如果MyPromise状态为pending,将两个回调函数push进回调数组中等待
this.callbacks.push({ onResolved, onRejected })
} else if (self.status === 'resolved') { //如果MyPromise状态为resolved,将onResolved直接调用
setTimeout(() => {
//检查.then中的回调有没有return返回值
const result = onResolved(self.data)
//如果没有return返回值,默认返回promise对象
if (result instanceof MyPromise) {
result.then((res => resolve(res), err => reject(err)))
return result
} else {
resolve(result)
}
})
} else {
setTimeout(() => {
onResolved(self.data)
})
}
})
}
MyPromise.prototype.catch = function (onRejected) { //.catch接受一个回调函数
if (this.status === 'pending') {
// 将回调函数放入callbacks数组中
this.callbacks.push({ onRejected })
} else if (this.status === 'rejected') {
setTimeout(() => {
onRejected(this.data)
})
}
}
// MyPromise构造函数接受一个执行函数
function MyPromise(executor) {
const self = this;
self.data = undefined;
self.callbacks = []
//设置promise对象初始状态为pending
self.status = 'pending'
//执行函数第一个参数为resolve回调
function resolve(value) {
//如果状态不是pending,则直接返回
if (self.status !== 'pending') {
return
}
// 执行resolve,promise对象状态变更
self.status = 'resolved';
// 拿到resolve中的值
self.data = value;
// 调用callbacks中的回调函数
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbacksObj => {
callbacksObj.onResolved(value)
});
})
}
}
// 执行函数第二个参数为rejecr回调
function reject(error) {
//如果状态不是pending,则直接返回
if (self.status !== 'pending') {
return
}
// 执行resolve,promise对象状态变更
self.status = 'rejected';
// 拿到resolve中的值
self.data = error;
// 调用callbacks中的回调函数
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbacksObj => {
callbacksObj.onRejected(value)
});
})
}
}
//使用try catch捕获错误
try {
// 在try内执行执行函数
executor(resolve, reject)
} catch (error) {
// 如果出错,默认执行reject
reject(error);
}
}
window.MyPromise = MyPromise
}(window))
测试
resolve
let MyPromiseTest = new MyPromise((resolve, reject) => {
resolve('resolve')
})
MyPromiseTest.then(res => {
console.log(res);
})
// resolve
let MyPromiseTest = new MyPromise((resolve, reject) => {
resolve('resolve');
})
MyPromiseTest.then(res => {
console.log(res);
})
.then(res => {
console.log('我是.then()后面的.then()');
})
// resolve
// 我是.then()后面的.then()
reject
let MyPromiseTest = new MyPromise((resolve, reject) => {
reject('reject')
})
MyPromiseTest.catch(err => {
console.log(err);
})
// reject
let MyPromiseTest = new MyPromise((resolve, reject) => {
console.log(a);
})
MyPromiseTest.catch(err => {
console.log('捕获错误' + ':' + err);
})
// 捕获错误:ReferenceError: a is not defined
来源:https://juejin.cn/post/7152725416040464421


猜你喜欢
- 有两种做法:os.walk()、pathlib库,个人感觉pathlib库的path.glob用来匹配文件比较简单。下面是第二种做法的实例(
- 使用cpan安装Net::SSH::Perl:cpan>install Net::SSH::Perl期间遇到了一些问题,记录在此,以备
- 前言编程是一件很快乐的事,实现一个目的,我们可以有很多方法路径,在这篇文章我们介绍一些JavaScript的奇技淫巧,仅供大家参考,各路大神
- 思路1.将姓名和单号填入excel表格里面2.读取excel表格,将所有姓名存到ExeclName这个list中,单号存到ExeclId3.
- 1、 利用操作符+比如:a = [1,2,3]b = [4,5,6]c = a+bc的结果:[1,2,3,4,5,6] 2 利用e
- 代码及注释如下#Auther Bob#--*--conding:utf-8 --*--#生产者消费者模型,这里的例子是这样的,有一个厨师在做
- 变量存储在内存中的值。这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存
- 本文实例讲述了python实现控制电脑鼠标和键盘,登录QQ的方法。分享给大家供大家参考,具体如下:import osfrom pynput.
- 本文实例讲述了golang操作mongodb的方法。分享给大家供大家参考。具体实现方法如下:package mainimport (&nbs
- 主要实现功能1、用户输入用户名,在用户名文件中查找对应的用户,若无对应用户名则打印输入错误2、用户名输入正确后,进行密码匹配。输入密码正确则
- 打算切换某个网站的主机,没想到遇到Php和Mysql中文乱码的问题。 以前的国外主机用的Mysql是4.x系列的,感觉还比较好,都无论GBK
- PHP count_chars() 函数实例返回一个字符串,包含所有在 "Hello World!" 中使用过的不同字符
- 本文以简单示例分析了python中关键字is与 ==的区别,供大家参考一下。首先说明一下Python学习中几个相关的小知识点。Python中
- 最近在工作当中遇到一个问题 有个页面需要添加一个浏览历史记录功能具体来说就是要记录下用户在此网站的点击历史 并把它们降序排列出来(只显示前6
- 1 简介费老师我在几年前写过的一篇文章(https://www.jb51.net/article/243348.htm)中,介绍过tqdm这
- <script language="javascript"> function window.onload(
- 几乎是一夜之间,微信小游戏《羊了个羊》火了。?这个依靠寻找相同元素消除方块的小游戏,凭借其“变态级别&rdquo
- 首先我们要在邮箱的设置中开通那个POP3然后我们要导入这些包import poplibfrom datetime import dateti
- names=["zhao00","qian01","sun02","l
- 本文实例讲述了Go语言算法之寻找数组第二大元素的方法。分享给大家供大家参考。具体如下:该算法的原理是,在遍历数组的时,始终记录当前最大的元素