JavaScript面试必考之实现手写Promise

目录
  • Promise手写
  • 框架
  • 完整代码
  • 测试
    • resolve
    • reject

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

到此这篇关于JavaScript面试必考之实现手写Promise的文章就介绍到这了,更多相关JavaScript手写Promise内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavsScript中Promise的错误捕获详解

    目录 我们需要在异步任务中准确的进行错误捕获,以便我们可以知道错误出在什么地方 我们再讨论then方法中的第二个参数和Promise.catch方法的区别 题: then方法的连续调用,怎么能够知道是第几个then方法报错了呢. 总结 我们需要在异步任务中准确的进行错误捕获,以便我们可以知道错误出在什么地方 如果对Promise和trycatch不够理解的话,很多时候会出现Promise中的错误无法被捕获的情况,本文来讨论这些情况 try catch try catch 只能捕获当前上下文中的错

  • JavaScript模拟实现Promise功能的示例代码

    模拟Promise的功能,  按照下面的步骤,一步一步 1. 新建是个构造函数 2. 传入一个可执行函数 函数的入参第一个为 fullFill函数 第二个为 reject函数: 函数立即执行, 参数函数异步执行 3. 状态一旦更改就不可以变更 只能 pending => fulfilled 或者 pending => rejected 4. then 的时候要处理入参的情况 successCallback 和failCallback 均可能为非函数 默认的 failCallback 一定要将异

  • Promise 链式调用原理精简示例

    目录 前言 代码 经典案例 解析 第一步 第二步 分析说明,此过程需结合上文中的案例一起阅读 总结 前言 在面试的过程中,总有一些面试官会问你,手写一个简易版的Promise得行不,得行的话就写一个出来看看,啪一哈,就把纸和笔给了你. 我们思索半天就写出来了个下面这个. 哦豁,高薪张开了它的翅膀,远离了我们. class Promise { constructor (resolve, reject) {} resolve () {} reject (){} then () {} catch ()

  • JS使用Promise时常见的5个错误总结

    目录 1.避免 Promise 地狱 2.在 Promise 中使用 try/catch 块 3.在 Promise 块内使用异步函数 4.在创建 Promise 后立即执行 Promise 块 5.不一定使用 Promise.all() 方法 总结 Promise 提供了一种优雅的方法来处理 JS 中的异步操作.这也是避免“回调地狱”的解决方案.然而,并没有多少开发人员了解其中的内容.因此,许多人在实践中往往会犯错误. 在本文中,介绍一下使用 promise 时的五个常见错误,希望大家能够避免

  • Promise抛出错误解决基础示例详解

    目录 then catch finally Promise.resolve Promise.reject then then 函数的会接收两个回调函数,一个是 onFulfilled 函数,一个是 onRejected 函数 如果这两个回调函数没有写返回值,默认会 return undefined; 进入下一个函数的 onFulfilled 函数中 const p = new Promise((resolve, reject) => { resolve(22); }); p.then( (suc

  • 捕获未处理的Promise错误方法

    为了保证可读性,本文采用意译而非直译,并且对源代码进行了大量修改.另外,本文版权归原作者所有,翻译仅用于学习. 使用Promise编写异步代码时,使用reject来处理错误.有时,开发者通常会忽略这一点,导致一些错误没有得到处理.例如: function main() { asyncFunc() .then(···) .then(() => console.log('Done!')); } 由于没有使用catch方法捕获错误,当asyncFunc()函数reject时,抛出的错误则没有被处理.

  • 详解JavaScript如何实现一个简易的Promise对象

    目录 前言 Promise的基础结构与用法 使用class类实现promise对象 写在最后 前言 实现一个简易的Promise对象,我们首先要了解几个相关的知识点: Promise对象的状态: pending(进行中).fulfilled(已成功)和rejected(已失败).只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态.这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变. Promise的参数: Promise构造函数接收一个函

  • Promise对象all与race方法手写示例

    目录 前言 Promise.all 介绍 手写 Promise.race 介绍 手写 前言 在理解了手写promsie.then的方法后,再来看它的其他方法,感觉真的简单了不少. Promise.all 介绍 Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例. const p = Promise.all([p1, p2, p3]); 上面代码中,Promise.all()方法接受一个数组作为参数,p1.p2.p3都是 Promise 实例.另外

  • JavaScript面试必考之实现手写Promise

    目录 Promise手写 框架 完整代码 测试 resolve reject Promise手写 Promise作为面试必考题,Promise的手写也是面试官必问的问题,所以对于Promise我们一定要了解透彻 框架 (function(window) { MyPromise.prototype.then = function (onResolved, onRejected) {} MyPromise.prototype.catch = function (onRejected) {} func

  • C语言实现手写JSON解析的方法详解

    目录 什么是JSON JSON支持的数据类型 JSON语法规则 JSON的解析 JSON基本语法 编写解析器 头文件 实现文件 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用来传输属性值或者序列性的值组成的数据对象. JSON是JavaScript的一个子集. 具有良好的可读性和便于快速编写的特性. JSON是独立于语言的文本格式,并且采用了类似C语言家族的一些习惯. JSON数据格式与语言无关,是目前网络中主流的数据传输格式之一,

  • JS实现手写parseInt的方法示例

    前言 本文主要给大家介绍了关于JS实现手写parseInt的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 手写parseInt的实现:要求简单一些,把字符串型的数字转化为真正的数字即可,但不能使用JS原生的字符串转数字的API,比如Number() 示例代码 function _parseInt(str, radix) { let str_type = typeof str; let res = 0; if (str_type !== 'string' &&

  • C语言实现手写Map(全功能)的示例代码

    目录 为啥需要Map结构 主流Map结构 数组+链表的Map 结构 hash函数 创建Map集合 扩容基数 扩容Map集合 给Map集合添加元素 打印Map集合 获取Map集合中的指定元素 判断键是否存在 判断值是否存在 删除Map集合中的指定元素 修改Map集合中的指定元素 迭代器 获取所有的key 获取所有的value 复制一个Map 将一个map集合合并到另一个map集合里 合并两个Map集合,返回一个新的Map集合 差集 交集 补集 并集 清除Map 为啥需要Map结构 假设,数据很少,

  • C语言实现手写Map(数组+链表+红黑树)的示例代码

    目录 要求 结构 红黑树和链表转换策略 hash 使用 要求 需要准备数组集合(List) 数据结构 需要准备单向链表(Linked) 数据结构 需要准备红黑树(Rbtree)数据结构 需要准备红黑树和链表适配策略(文章内部提供,可以自行参考) 建议先去阅读我博客这篇文章C语言-手写Map(数组+链表)(全功能)有助于理解 hashmap使用红黑树的原因是: 当某个节点值过多的时候那么链表就会非常长,这样搜索的时候查询速度就是O(N) 线性查询了,为了避免这个问题我们使用了红黑树,当链表长度大于

  • Python 面试中 8 个必考问题

    1.下面这段代码的输出结果是什么?请解释. def extendList(val, list=[]): list.append(val) return list list1 = extendList(10) list2 = extendList(123,[]) list3 = extendList('a') print "list1 = %s" % list1 print "list2 = %s" % list2 print "list3 = %s&quo

  • JavaScript面试出现频繁的一些易错点整理

    1.前言 这段时间,金三银四,很多人面试,很多人分享面试题.在前段时间,我也临时担任面试官,为了大概了解面试者的水平,我也写了一份题目,面试了几个前端开发者.在这段时间里面,我在学,在写设计模式的一些知识,想不到的设计模式的这些知识,就是面试题里面,频繁让人掉坑的考点. 所以,今天就总结一下,那些让人掉坑的考点.下面话不多说了,来一起看看详细的介绍吧. 2.面向对象编程 关于面向对象和面向过程,个人觉得这两者不是绝对独立的,而是相互相成的关系.至于什么时候用面向对象,什么时候用面向过程,具体情况

  • 数据库基本概念面试必问

    今天小编给大家分享日常收集整理有关数据库基本概念,对大家在今后的工作非常有帮助. 1.超键.候选键.主键.外键 超键:在关系中能唯一标识元组的属性集称为关系模式的超键.一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键.超键包含候选键和主键. 候选键:是最小超键,即没有冗余元素的超键. 主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合.一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null). 外键:在一个表中存在的另一个表的主键称此表的外键.

  • Redis面试必会的题目

    Redis 支持哪几种数据类型? string:最基本的数据类型,二进制安全的字符串,最大512M list:按照添加顺序保持顺序的 字符串列表 set:无序的字符串集合,不存在重复的元素 sorted set:已排序的字符串集合 hash:key/value对的一种集合 Redis是单进程的还是单线程的? Redis是单进程单线程的,Redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销. Redis为什么是单线程的? 多线程处理会设计到锁,而且多线程处理会设计到线程切换

  • JavaScript面试之如何实现数组拍平(扁平化)方法

    目录 1 什么叫数组拍平? 2 JS标准库中的数组拍平方法 3 实现一个flat方法 3.1 如何遍历一个数组 3.2 如何判断元素是否为数组 3.3 递归 3.4 初步实现flat方法 4 优化 4.1 指定展开深度 4.2 数组空位处理 4.2.1 for...of增加空位判断 4.2.2 forEach.map方法遍历 4.2.3 reduce方法 5 其他 5.1 栈 5.2 改进 总结 1 什么叫数组拍平? 概念很简单,意思是将一个"多维"数组降维,比如: // 原数组是一个

随机推荐