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

模拟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;
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码云笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值