JavaScript模拟实现Promise功能的示例代码
作者:菜鸟小于
这篇文章主要为大家详细介绍了JavaScript如何模拟实现Promise功能,文中的示例代码讲解详细,对我们学习JavaScript有一定的帮助,需要的可以参考一下
模拟Promise的功能, 按照下面的步骤,一步一步
1. 新建是个构造函数
2. 传入一个可执行函数 函数的入参第一个为 fullFill函数 第二个为 reject函数; 函数立即执行, 参数函数异步执行
3. 状态一旦更改就不可以变更 只能 pending => fulfilled 或者 pending => rejected
4. then 的时候要处理入参的情况 successCallback 和failCallback 均可能为非函数
默认的 failCallback 一定要将异常抛出, 这样下一个promise便可将其捕获 异常冒泡的目的
5. then 中执行回调的时候要捕获异常 将其传给下一个promise
- 如果promise状态未变更 则将回调方法添加到对应队列中
- 如果promise状态已经变更 需要异步处理成功或者失败回调
- 因为可能出现 回调结果和当前then返回的Promise一致 从而导致死循环问题
6. catch只是then的一种特殊的写法 方便理解和使用
7. finally 特点
- 不过resolve或者reject都会执行
- 回调没有参数
- 返回一个Promise 且值可以穿透到下一个then或者catch
8. Promise.resolve, Promise.reject 根据其参数返回对应的值 或者状态的Promise即可
9. Proise.all 特点
- 返回一个Promise
- 入参是数组 resolve的情况下出参也是数组 且结果顺序和调用顺序一致
- 所有的值或者promise都完成才能resolve 所有要计数
- 只要有一个为reject 返回的Promise便reject
10. Proise.race 特点
- 返回一个Promise
- 入参是数组 那么出参根据第一个成功或者失败的参数来确定
- 只要有一个resolve 或者reject 便更改返回Promise的状态
const PENDING = 'pending' //等待 const FULFILLED = 'fulfilled' //成功 const REJECTED = 'rejected' //失败 const fulfilledCallback = [] //成功回调函数 const rejectedCallback = [] //失败回调函数 class MyPromise { constructor (executor) { try{ executor(this.resolve, this.reject) } catch (e){ this.reject(e) } } status = PENDING//promise的状态 value = undefined//成功之后的值 reason = undefined//失败之后的值 fulfilledCallback = [] //成功回调函数 rejectedCallback = [] //失败回调函数 resolve = value => { //如果状态不是等待, 阻止程序继续往下执行 if(this.status !== PENDING){ return } this.status = FULFILLED this.value = value //判断成功回调是否存在,如果存在, 调用 // this.fulfilledCallback && this.fulfilledCallback(this.value) while(this.fulfilledCallback.length) this.fulfilledCallback.shift()() } reject = reason => { //如果状态不是等待, 阻止程序继续往下执行 if(this.status !== PENDING){ return } this.status = REJECTED this.reason = reason //判断失败回调是否存在,如果存在, 调用 // this.rejectedCallback && this.rejectedCallback(this.reason) while(this.rejectedCallback.length) this.rejectedCallback.shift()() } then = (fulfilledCallback, rejectedCallback) => { fulfilledCallback = fulfilledCallback ? fulfilledCallback : value => value rejectedCallback = rejectedCallback ? rejectedCallback : reason => {throw reason} let promise2 = new MyPromise((resolve, reject) => { //判断状态 if(this.status === FULFILLED){ setTimeout(() => { try { //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject, //如果是普通值,直接调用resolve let x = fulfilledCallback(this.value) //外面加载完,才能获取到promise2,用异步解决 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }else if(this.status === REJECTED){ setTimeout(() => { try { //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject, //如果是普通值,直接调用resolve let x = rejectedCallback(this.reason) //外面加载完,才能获取到promise2,用异步解决 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }else{ //等待状态 this.fulfilledCallback.push(() => { setTimeout(() => { try { //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject, //如果是普通值,直接调用resolve let x = fulfilledCallback(this.value) //外面加载完,才能获取到promise2,用异步解决 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }); this.rejectedCallback.push(() => { setTimeout(() => { try { //判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject, //如果是普通值,直接调用resolve let x = rejectedCallback(this.reason) //外面加载完,才能获取到promise2,用异步解决 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }); } }) return promise2 } static all (array) { let result= [] let index = 0; return new MyPromise((resolve, reject) => { function addData (key, value) { result[key] = value index++ if (index === array.length) { resolve(result) } } for (let i = 0; i < array.length; i++) { if (array[i] instanceof MyPromise) { //promise对象 array[i].then(value => addData(i, value), reason => reject(reason)) } else { //普通值, 放到数组里 addData(i, array[i]) } } }) } static resolve (value) { if(value instanceof MyPromise) return value return new MyPromise(resolve => resolve(value)) } finally (callback) { return this.then(value => { return MyPromise.resolve(callback()).then(() => value) }, reason => { return MyPromise.resolve(callback()).then(() => {throw reason}) }) } catch (rejectedCallback) { return this.then(undefined, rejectedCallback) } } function resolvePromise(promise2,x,resolve, reject){ if(x === promise2){ return reject(new TypeError('啦啦啦啦')) } if(x instanceof MyPromise){ //是promise //往下直接传 x.then(resolve,reject) }else{ //普通值 resolve(x) } } module.exports = MyPromise;
到此这篇关于JavaScript模拟实现Promise功能的示例代码的文章就介绍到这了,更多相关JavaScript实现Promise功能内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!