怎么使用JavaScript手写一个Promise


这篇文章主要介绍“怎么使用JavaScript手写一个Promise”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用JavaScript手写一个Promise”文章能帮助大家解决问题。首先我们从使用的角度来分析一下Promise,然后编写一个最简单版本的Promise。Promise就是一个类,在执行这个类的时候,需要传递一个执行器(回调函数)进去,执行器会立即执行。Promise中的状态分为三个,分别是:pending→等待fulfilled→成功rejected→失败状态的切换只有两种,分别是:pending→fulfilledpending→rejected一旦状态发生改变,就不会再次改变:执行器中的两个参数,分别是resolve和reject,其实就是两个回调函数,调用resolve是从pending状态到fulfilled,调用reject是从状态pending到rejected。传递给这两个回调函数的参数会作为成功或失败的值。Promise的实例对象具有一个then方法,该方法接受两个回调函数,分别来处理成功与失败的状态,then方法内部会进行判断,然后根据当前状态确定调用的回调函数。then方法应该是被定义在原型对象中的。then的回调函数中都包含一个值,如果是成功,表示成功后返回的值;如果是失败就表示失败的原因。根据我们上面的分析,写出如下代码:现在我们就来写一段代码验证一下上面的代码验证resolve:验证reject:验证状态不可变:如果我们的代码中存在异步操作,我们自己写的Promise将毫无用处,例如下面这段代码:这段代码2000ms后没有任何输出,为了解决这个问题我们将对自己编写的类进行如下操作:创建两个实例方法用于存储我们传入的成功与失败的处理逻辑。为then方法添加状态为pending时的处理逻辑,这时将传递进来的属性保存到实例上。在成功或者失败时调用相应的传递进来的回调函数(实例属性存在函数的情况下)。实现代码如下:这里的this.onFulfilled && this.onFulfilled(this.value)表示如果该属性存在就调用这个方法。现在我们重新执行一开始上面那一段代码,2s后会成功输出成功。Promise实例中存在要给then方法,允许我们在Promise实例中链式调用,每个then方法还会返回一个Promise实例,如下图所示:Promise实例方法then是可以多次进行调用,而我们现在自己封装的却执行调用一次,现在根据新需要来重新改写我们的代码,实现思路如下:定义可以存储多个回调的数组,用于存储多个回调函数。如果是同步执行的代码,执行后立即知道执行结果,所以可以直接调用回调函数。如果是异步代码,需要将每次回调函数保存到数组中,然后状态变化时依次调用函数。实现代码如下:这里我们通过数组的shift()方法,该方法删除数组的第一个元素,并返回,返回的这个值正好是一个回调函数,然后调用该函数即可实现该功能。想要实现then的链式调用,主要解决两个问题:返回的是一个新的MyPormise实例。then的返回值作为下一次的链式调用的参数。这里分为两种情况:直接返回一个值,可以直接作为值使用返回一个新的MyPormise实例,此时就需要判断其状态实现代码如下:在Promise中,如果then方法返回的是自己的promise对象,则会发生promise的嵌套,这个时候程序会报错,测试代码如下:想要解决这个问题其实我们只需要在then方法返回的MyPromise实例对象与then中回调函数返回的值进行比对,如果相同的返回一个reject的MyPromise实例对象,并创建一个TypeError类型的Error。实现代码如下:这里then方法中的setTimeout的作用并不是延迟执行,而是为了调用resolvePromise函数时,保证创建的promise存在。到目前为止我们现实的Promise并没有对异常做任何处理,为了保证代码的健壮性,我们需要对异常做一些处理。现在我们需要对执行器进行异常捕获,如果发生异常,就将我们的状态修改为rejected。捕获执行器的错误也比较简单,只需要在构造函数中加入try...catch语句就可以,实现代码如下:测试代码如下:现在我们需要对th免费云主机域名en中的异常捕获到,并在下一次链式调用中传递到then的第二个函数中,实现的方式也是通过try...catch语句,示例代码如下:测试代码如下:现在只对成功状态的then进行的链式调用以及错误处理,错误与异步状态未进行处理,其实处理起来也是一样的,示例代码如下:测试代码如下:Promise中的then方法其实是两个可以可选参数,如果我们不传递任何参数的话,里面的结果是向下传递的,直到捕获为止,例如下面这段代码:这段代码可以理解为:所以说我们只需要在没有传递回调函数时,赋值一个默认的回调函数即可。实现代码如下:关于all()方法的使用,可以参数Promise.all()。简单的说Promise.all()会将多个Promise实例包装为一个Promise实例,且顺序与调用顺序一致,示例代码如下:在这段代码中,我们的p1的执行是延迟了2s的,这里如果不使用Promise.all()的话最终顺序是与我们调用不同的。现在我们来分析一下all()的实现思路:all()方法可以通过类直接调用,所以是一个静态方法all()方法接收一个数组,数组中的值可以是一个普通值,也可以是一个MyPromise的实例对象return一个新的MyPromise实例对象遍历数组中的每一个值,判断值得类型,如果是一个普通值得话直接将值存入一个数组;如果是一个MyPromise的实例对象的话,会调用then方法,然后根据执行后的状态,如果失败的话调用新的MyPromise实例对象中的rejecte,如果是成功话将这个值存入一个数组存入数组时计数,如果存入的数量达到传入的数组长度,说明调用完毕,执行resolve并将最终的结果数组作为参数返回。实现代码:关于Promise.resolve()方法的用法可以参考Promise.resolve()Promise.reject()我们实现的思路主要如下:该方法是一个静态方法该方法接受的如果是一个值就将该值包装为一个MyPromise的实例对象返回,如果是一个MyPromise的实例对象,调用then方法返回。实现代码如下:关于finally方法可参考finally()实现该方法的实现代码如下:测试:关于catch方法可以参考catch(),实现该方法其实非常简单,只需要在内部调用then方法,不传递第一个回调函数即可,实现代码如下:测试如下:关于“怎么使用JavaScript手写一个Promise”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注百云主机行业资讯频道,小编每天都会为大家更新不同的知识点。

相关推荐: bootstrap自适应指的是什么

这篇文章主要介绍“bootstrap自适应指的是什么”,在日常操作中,相信很多人在bootstrap自适应指的是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”bootstrap自适应指的是什么”的疑惑有所帮助!接下来,请跟着…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 03/20 19:28
Next 03/20 19:28

相关推荐