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
  • asp之家 网络编程 m.aspxhome.com