JavaScript面试必考之实现手写Promise
作者:你也向往长安城吗 时间:2024-04-16 10:38:49
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
标签:JavaScript,手写,Promise
0
投稿
猜你喜欢
微信小程序学习笔记之文件上传、下载操作图文详解
2023-09-07 21:13:21
sql 随机抽取几条数据的方法 推荐
2024-01-29 09:15:32
mysql 存储过程中变量的定义与赋值操作
2024-01-22 18:44:55
Python编程实现小姐姐跳舞并生成词云视频示例
2023-10-16 17:38:15
ES6记录异步函数的执行时间详解
2024-04-10 16:18:56
Ubuntu手动安装mysql5.7.10
2024-01-16 11:53:56
oracle 发送邮件 实现方法
2009-06-10 17:49:00
Ruby序列化和持久化存储(Marshal、Pstore)操作方法详解
2024-04-26 17:20:16
PHP字典树(Trie树)定义与实现方法示例
2023-11-15 00:39:50
Python中if语句的基本格式实例代码
2023-12-02 14:31:20
ubuntu 18.04搭建python环境(pycharm+anaconda)
2023-09-23 20:01:56
mysql Load Data InFile 的用法
2009-09-06 12:08:00
Python列表对象实现原理详解
2022-09-07 10:24:58
详解vue项目中调用百度地图API使用方法
2024-05-09 09:38:29
修改asp代码防止被杀毒软件误删
2007-10-07 12:32:00
CentOS7.4手动安装MySQL5.7的方法
2024-01-28 01:12:20
在线HTML编辑器原理(eweb原理)
2009-01-08 12:25:00
golang三元表达式的使用方法
2023-08-28 14:34:09
python高阶爬虫实战分析
2023-02-04 14:11:10
Windows Server 2003 服务器安全设置--防火墙篇
2010-07-22 22:45:00