前端面试手写-手写一个promise

1,102 阅读12分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

得不得奖的无所谓希望能强迫自己闯一关

前言

持续记录学习手写promise

  • 1.定义一个基础promise方法并then结果
  • 2.异步执行问题
  • 3.then方法链式调用
  • 4.then返回Promise处理与then穿透传递
  • 5.then代码冗余优化与错误处理catch
  • 6.Promise.resolve 与 Promise.reject
  • 7.Promise.all
  • 8.Promise.race 实践时可同步与原生Promise作对比,更好的了解Promise执行

1.定义一个基础promise方法并且then获取结果

(function () {
  function Typromise(executor) { // executor new Promise传进来的方法
    this.state = 'pending' // promise状态,有 fulfilled rejected pending 三种状态
    this.result = '' // new Promise执行的结果
    // 定义new Promise时 executor传进来的两个方法 resolve,reject
    let resolve = (value) => {
      if (this.state === 'pending') { // 在pending时状态可变,经 resolve 后就不会再变
        this.state = 'fulfilled'
        this.result = value
      }
    }
    let reject = (reason) => {
      if (this.state === 'pending') { // 在pending时状态可变,经 reject 后就不会再变
        this.state = 'rejected'
        this.result = reason;
      }
    }
    this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
      if (this.state === 'fulfilled') { // resolve后,状态为fufilled,执行传进来的onFulfilled方法
        onFulfilled(this.result)
      }
      if (this.state === 'rejected') { // reject后,状态为rejected,执行传进来的onRejected方法
        onRejected(this.result)
      }
    }
    // 执行executor方法时有可能new Promise里面执行出错的时候,这里需要try catch
    try {
      executor(resolve, reject) // 此处执行new Promise时里面执行 resolve 或 reject 方法
    } catch (error) {
      reject(error) // new Promise 里方法报错时的处理
    }
  }
  window.Typromise = Typromise
})()

对比测试

console.log('1.-----------------手写promise');
let ty = new Typromise((resolve, reject) => {
    resolve('fulfilled-手写');
    // reject('reject-手写');
    console.log('2.new Typromise')
}).then(value => { 
    console.log('4.value: ', value);
}, error => { 
    console.log('4.error: ', error);
})
console.log('3.-----------------ty')

console.log('1.-----------------原生Promise');
let p = new Promise((resolve, reject) => {
    resolve('fulfilled-官方');
    // reject('reject-官方');
    console.log('2.new Promise')
}).then(value => { 
    console.log('4.value: ', value);
}, error => { 
    console.log('4.error: ', error);
})
console.log('3.-----------------p')

image.png 结论:上面测试说明第4的输出应该是后于第3的,所以可以认为then里面的方法应该是异步的

2.异步执行问题

1.then里的方法是异步执行的

修改then方法为异步执行

function Typromise(executor){
    ···
    this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
      if (this.state === 'fulfilled') { // resolve后,状态为fufilled,执行传进来的onFulfilled方法
        setTimeout(() => {
          onFulfilled(this.result)
        });
      }
      if (this.state === 'rejected') { // reject后,状态为rejected,执行传进来的onRejected方法
        setTimeout(() => {
          onRejected(this.result)
        });
      }
    }
    ···
}

image.png

2.new Promise里的异步执行问题

测试:new Promise存在异步执行 resolvereject 时的情况

console.log('1.-----------------手写promise');
let ty = new Typromise((resolve, reject) => {
    setTimeout(() => {
        // resolve('fulfilled-手写');
        reject('reject-手写');
        console.log('2.new Typromise')
    }, 1000);
}).then(value => {
    console.log('4.value: ', value);
}, error => {
    console.log('4.error: ', error);
})
console.log('3.-----------------ty')

console.log('1.-----------------原生Promise');
let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        // resolve('fulfilled-官方');
        reject('reject-官方');
        console.log('2.new Promise')
    }, 1000);
}).then(value => { 
    console.log('4.value: ', value);
}, error => { 
    console.log('4.error: ', error);
})
console.log('3.-----------------p')

image.png 结论:上图测试说明在new Promise里面使用setTimeout异步执行后并没有执行then方法里的回调返回值,以至于结果4.value:fulfilled-手写 并没有出现在log里

修改then方法里当遇到new Promise异步执行进入等待pending状态时的逻辑

  • 1.先定义一个存储延迟执行方法的变量 callback = { }
  • 2.由于new Promise里的resolverejectsetTimeout里异步执行。所以then会先执行,此时statependingthen执行时先将then里传进来的onFulfilledonRejected存入callback中等待异步的resolvereject调用
  • 3.在resolvereject调用时,执行onFulfilledonRejected方法 以下标⭐️⭐️为修改的地方
(function () {
  function Typromise(executor) { // executor new Promise传进来的方法
    this.state = 'pending' // promise状态,有 fulfilled rejected pending 三种状态
    this.result = '' // new Promise执行的结果
    this.callback = {} // 定义一个收集方法调用的对象  ⭐️⭐️修改⭐⭐️---------------1.定义callback变量存储
    // 定义new Promise时 executor传进来的两个方法 resolve,reject
    let resolve = (value) => {
      if (this.state === 'pending') { // 在pending时状态可变,经 resolve 后就不会再变
        this.state = 'fulfilled'
        this.result = value
        // ⭐️⭐️修改⭐️⭐---------------3.等待调用
        if (this.callback.onFulfilled) { 
            this.callback.onFulfilled(this.result)
        }
      }
    }
    let reject = (reason) => {
      if (this.state === 'pending') { // 在pending时状态可变,经 reject 后就不会再变
        this.state = 'rejected'
        this.result = reason;
        // ⭐️⭐️修改⭐️⭐---------------3.等待调用
        if (this.callback.onRejected) {
            this.callback.onRejected(this.result)
        }
      }
    }
    this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
      if (this.state === 'pending') { // 等待状态时,先将回调方法存起来
        this.callback = { // ⭐️⭐修改⭐️⭐---------------------- 2.此处存储异步执行的方法
          onFulfilled,
          onRejected
        }
      }
      if (this.state === 'fulfilled') { // resolve后,状态为fufilled,执行传进来的onFulfilled方法
        setTimeout(() => {
          onFulfilled(this.result)
        });
      }
      if (this.state === 'rejected') { // reject后,状态为rejected,执行传进来的onRejected方法
        setTimeout(() => {
          onRejected(this.result)
        });
      }
    }
    // 执行executor方法时有可能new Promise里面执行出错的时候,这里需要try catch
    try {
      executor(resolve, reject) // 此处执行new Promise时里面执行 resolve 或 reject 方法
    } catch (error) {
      reject(error) // new Promise 里方法报错时的处理
    }
  }
  window.Typromise = Typromise
})()

测试正常 image.png

3.then方法链式调用

1.第二个then的调用

分析:

  • 1.怎么执行第二个then呢?前面了解到then方法是通过 new Promiseresolvereject后才执行的。
  • 2.所以手写的then方法里也应该是一个Promise才能继续执行到then
  • 3.我们在then再执行一次 resolvereject就会继续执行到下一个then,所以在then里返回一个新的 Promise并执行resolvereject。 改造 then 方法
  • 1.将then里面的方法用 new Typromise 包起来并返回
  • 2.在第一个 then 里执行 resolvereject 将值继续返给下一个then 以下标⭐️⭐️为修改的地方
···
this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
 let p = new Typromise((resolve, reject) => { // ⭐️⭐️修改⭐⭐️---------------1.
    if (this.state === 'pending') { // 等待状态时,先将回调方法存起来
      this.callback = {
        onFulfilled,
        onRejected
      }
    }
    if (this.state === 'fulfilled') { // resolve后,状态为fufilled,执行传进来的onFulfilled方法
      setTimeout(() => {
        let res = onFulfilled(this.result) // ⭐️⭐️修改⭐⭐️---------------2.
        resolve(res) // ⭐️⭐️修改⭐⭐️---------------2.
      });
    }
    if (this.state === 'rejected') { // reject后,状态为rejected,执行传进来的onRejected方法
      setTimeout(() => {
        let res = onRejected(this.result) // ⭐️⭐️修改⭐⭐️---------------2.
        resolve(res) // ⭐️⭐️修改⭐⭐️---------------2.这为什么也用resolve,查看下面运行结果分析
      });
    }
  })
  return p // ⭐️⭐️修改⭐⭐️---------------1.
}
···

测试结果:

console.log('1.-----------------手写promise');
let ty = new Typromise((resolve, reject) => {
    resolve('fulfilled-手写');
    // reject('reject-手写');
    console.log('2.new Typromise')
}).then(value => {
    return value
}, error => { 
}).then(value => {
    console.log('4.value: ', value);
}, error => {
    console.log('4.error: ', error);
})
console.log('3.-----------------ty')

console.log('1.-----------------原生Promise');
let p = new Promise((resolve, reject) => {
    resolve('fulfilled-官方');
    // reject('reject-官方');
    console.log('2.new Promise')
}).then(value => {
    return value
}, error => { 
}).then(value => { 
    console.log('4.value: ', value);
}, error => { 
    console.log('4.error: ', error);
})
console.log('3.-----------------p')

image.png 针对代码中为什么在 this.state === 'rejected' 时也用resolve 是因为新的 promise 默认的状态它就是成功的,即使第一个then执行的是reject方法也会返回成功到第二个then,是不会影响到我们下一个then的,可以看以下测试结果对比 image.png

2.第三个then以及之后then的链式调用

分析问题:

  • 1.经过上面的改造,进行第三个then调用时的结果并不相同,手写的promise执行完第二个then后,第三个then没有执行 image.png
  • 2.我在then里面打印了 stateresult,发现第二个then开始的state是在pending状态,并未改变
console.log('this.state: ', this.state);
console.log('this.result: ', this.result);

image.png 改造 then 方法

  • 所以我将thenthis.state === 'pending'里的方法也执行 resolvereject 将值继续返给下一个then 基于上面then代码的基础上,以下标⭐️⭐️为修改的地方
···
this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
  let p = new Typromise((resolve, reject) => {
    if (this.state === 'pending') { // 等待状态时,先将回调方法存起来
     // ⭐️⭐️修改⭐⭐️---------------1.这里改造整个callback
      this.callback = {
        onFulfilled:value=>{
          let res = onFulfilled(this.result)
          resolve(res)
        },
        onRejected:value=>{
          let res = onRejected(this.result)
          resolve(res)
        }
      }
    }
    if (this.state === 'fulfilled') { // resolve后,状态为fufilled,执行传进来的onFulfilled方法
      setTimeout(() => {
        let res = onFulfilled(this.result)
        resolve(res)
      });
    }
    if (this.state === 'rejected') { // reject后,状态为rejected,执行传进来的onRejected方法
      setTimeout(() => {
        let res = onRejected(this.result)
        resolve(res)
      });
    }
  })
  return p
}
···

测试结果

console.log('1.-----------------手写promise');
let ty = new Typromise((resolve, reject) => {
    resolve('fulfilled-手写');
    // reject('reject-手写');
    console.log('2.new Typromise')
}).then(value => {
    return value
}, error => { 
}).then(value => {
    return value
}, error => { 
}).then(value => {
    console.log('4.value: ', value);
}, error => {
    console.log('4.error: ', error);
})
console.log('3.-----------------ty')

console.log('1.-----------------原生Promise');
let p = new Promise((resolve, reject) => {
    resolve('fulfilled-官方');
    // reject('reject-官方');
    console.log('2.new Promise')
}).then(value => {
    return value
}, error => { 
}).then(value => {
    return value
}, error => { 
}).then(value => { 
    console.log('4.value: ', value);
}, error => { 
    console.log('4.error: ', error);
})
console.log('3.-----------------p')

image.png 结论:之后只要有返回值继续增加then执行也会一直调用,就形成了链式调用

4.then方法返回promise的处理与then穿透

1.返回promise处理

  • 分析:我们手写的promisethen里返回promise时下一个then没有返回value而是直接返回了promise image.png 继续改造 then方法,将返回的两种类型进行区分,区分return的是 Typromise类型还是纯 值类型
    基于上面then代码的基础上,以下标⭐️⭐️为修改的地方
this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
  let p = new Typromise((resolve, reject) => {
    if (this.state === 'pending') { // 等待状态时,先将回调方法存起来
      this.callback = {
        onFulfilled: value => {
          let res = onFulfilled(this.result)
          // START⭐️⭐️修改⭐⭐️---------------resolve(res)修改
          if (res instanceof Typromise) {
            res.then(value=>{
              resolve(value)
            },reason=>{
              reject(reason)
            })
          } else {
            resolve(res)
          }
          // END⭐️⭐️修改⭐⭐️---------------resolve(res)修改
        },
        onRejected: value => {
          let res = onRejected(this.result)
          // START⭐️⭐️修改⭐⭐️---------------resolve(res)修改
          if (res instanceof Typromise) {
            res.then(value=>{
              resolve(value)
            },reason=>{
              reject(reason)
            })
          } else {
            reject(res)
          }
          // END⭐️⭐️修改⭐⭐️---------------resolve(res)修改
        },
      }
    }
    if (this.state === 'fulfilled') { // resolve后,状态为fufilled,执行传进来的onFulfilled方法
      setTimeout(() => {
        let res = onFulfilled(this.result)
        // START⭐️⭐️修改⭐⭐️---------------resolve(res)修改
        if (res instanceof Typromise) {
          res.then(value=>{
            resolve(value)
          },reason=>{
            reject(reason)
          })
        } else {
          resolve(res)
        }
        // END⭐️⭐️修改⭐⭐️---------------resolve(res)修改
      });
    }
    if (this.state === 'rejected') { // reject后,状态为rejected,执行传进来的onRejected方法
      setTimeout(() => {
        let res = onRejected(this.result)
        // START⭐️⭐️修改⭐⭐️---------------resolve(res)修改
        if (res instanceof Typromise) {
          res.then(value=>{
            resolve(value)
          },reason=>{
            reject(reason)
          })
        } else {
          reject(res)
        }
        // END⭐️⭐️修改⭐⭐️---------------resolve(res)修改
      });
    }
  })
  return p
}

可以看出上面有很多冗余的代码,完善功能后下面将进行优化
测试结果:

console.log('1.-----------------手写promise');
let ty = new Typromise((resolve, reject) => {
    resolve('fulfilled-手写');
    // reject('reject-手写');
    console.log('2.new Typromise')
}).then(value => {
    return new Typromise((resolve,reject)=>{
        resolve(value)
        // reject(value)
    })
}, error => { 
}).then(value => {
    return new Typromise((resolve,reject)=>{
        resolve(value)
        // reject(value)
    })
}, error => { 
}).then(value => {
    console.log('4.value: ', value);
}, error => {
    console.log('4.error: ', error);
})
console.log('3.-----------------ty')

console.log('1.-----------------原生Promise');
let p = new Promise((resolve, reject) => {
    resolve('fulfilled-官方');
    // reject('reject-官方');
    console.log('2.new Promise')
}).then(value => {
    return new Promise((resolve,reject)=>{
        resolve(value)
        // reject(value)
    })
}, error => { 
}).then(value => {
    return new Promise((resolve,reject)=>{
        resolve(value)
        // reject(value)
    })
}, error => { 
}).then(value => { 
    console.log('4.value: ', value);
}, error => { 
    console.log('4.error: ', error);
})
console.log('3.-----------------p')

image.png

2.then穿透传递

  • 分析:原生的then()即使传递了一个空值下一个then()也能收到promiseresolvereject执行之后的值,而手写由于传了空值而直接报错,所以我们需要在then里做下方法非空校验并且还需要穿透传递值 image.png 继续改造 then 方法
    基于上面then代码的基础上,以下标⭐️⭐️为修改的地方
···
this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
    // START⭐️⭐️修改⭐⭐️---------------新增传入的函数判断
    if (!(onFulfilled instanceof Function)) {
        onFulfilled = value => value // 当是空时,直接把值传给下一个then
    }
    if (!(onRejected instanceof Function)) {
        onRejected = reason => reason // 当是空时,直接把值传给下一个then
    }
    // END⭐️⭐️修改⭐⭐️---------------新增传入的函数判断
    let p = new Typromise((resolve, reject) => {
    ···
    })
    ···
})

测试结果:

console.log('1.-----------------手写promise');
let ty = new Typromise((resolve, reject) => {
    resolve('fulfilled-手写');
    // reject('reject-手写');
    console.log('2.new Typromise')
}).then().then(value => {
    console.log('4.value: ', value);
}, error => {
    console.log('4.error: ', error);
})
console.log('3.-----------------ty')

console.log('1.-----------------原生Promise');
let p = new Promise((resolve, reject) => {
    resolve('fulfilled-官方');
    // reject('reject-官方');
    console.log('2.new Promise')
}).then().then(value => { 
    console.log('4.value: ', value);
}, error => { 
    console.log('4.error: ', error);
})
console.log('3.-----------------p')

image.png

5.then错误处理与代码冗余优化

1.返回promise类型约束,预防用户在 new Promise时返回了自身 陷入死循环

let p = new Promise((resolve, reject) => {
    return p; // 在此返回了自身
}).then(value => {
    return new Promise(resolve=>{
        resolve(value)
    })
}, error => { 
})

加入检验

if (p === res) {
    throw new TypeError('Chaining cycle detected for promise #<Typ romise>')
}

2.错误处理

每当then里执行错误的语法直接报错时try catch处理reject一下让错误能被下一个then()的reject捕获 image.png

3.封装冗余代码parse并贴上完整代码

  • 封装parse方法处理冗余代码
  • 实现catch()方法
    promise.then().catch() catch()方法返回一个Promise,并且处理拒绝的情况。因为then方法的第二个参数其实就是做这件事的,catch只是另一个名称罢了。当then方法的第二参数没有时,会自动由catch接手 以下标⭐️⭐️为修改的地方
(function () {
  function Typromise(executor) { // executor new Promise传进来的方法
    this.state = 'pending' // promise状态,有 fulfilled rejected pending 三种状态
    this.result = '' // new Promise执行的结果
    this.callback = {} // 定义一个收集方法调用的对象
    // START⭐️⭐️修改⭐⭐️---------------新增parse封装方法处理代码冗余
    let parse = (p, res, resolve, reject, type) => {
      if (p === res) { // 返回promise类型约束,预防用户在 new Promise时返回自身 陷入死循环
        throw new TypeError('Chaining cycle detected for promise #<Typromise>')
      }
      if (res instanceof Typromise) {
        /*  res.then(value=>{
           resolve(value)
         },value=>{
           reject(value)
         }) */
        res.then(resolve, reject) // 上面方法可简写
      } else {
        type == 'resolve' ? resolve(res) : reject(res)
      }
    }
    // END⭐️⭐️修改⭐⭐️---------------新增parse封装方法处理代码冗余
    // 定义new Promise时 executor传进来的两个方法 resolve,reject
    let resolve = (value) => {
      if (this.state === 'pending') { // 在pending时状态可变,经 resolve 后就不会再变
        this.state = 'fulfilled'
        this.result = value
        if (this.callback.onFulfilled) {
          setTimeout(() => {
            this.callback.onFulfilled(this.result)
          });
        }
      }
    }
    let reject = (reason) => {
      if (this.state === 'pending') { // 在pending时状态可变,经 reject 后就不会再变
        this.state = 'rejected'
        this.result = reason;
        if (this.callback.onRejected) {
          setTimeout(() => {
            this.callback.onRejected(this.result)
          });
        }
      }
    }
    this.then = (onFulfilled, onRejected) => { // then接收两个方法,resolve 或者 reject后执行
      if (!(onFulfilled instanceof Function)) {
        onFulfilled = value => value // 当是空时,直接把值传给下一个then
      }
      if (!(onRejected instanceof Function)) {
        onRejected = reason => reason // 当是空时,直接把值传给下一个then
      }
      let p = new Typromise((resolve, reject) => {
        if (this.state === 'pending') { // 等待状态时,先将回调方法存起来
          this.callback = {
            onFulfilled: value => {
              // START⭐️⭐️修改⭐⭐️---------------捕获错误
              try {
                parse(p, onFulfilled(value), resolve, reject, 'resolve')
              } catch (error) {
                reject(error)
              }
              // END⭐️⭐️修改⭐⭐️---------------捕获错误
            },
            onRejected: value => {
              // START⭐️⭐️修改⭐⭐️---------------捕获错误
              try {
                parse(p, onRejected(value), resolve, reject, 'reject')
              } catch (error) {
                reject(error)
              }
              // END⭐️⭐️修改⭐⭐️---------------捕获错误
            },
          }
        }
        if (this.state === 'fulfilled') { // resolve后,状态为fufilled,执行传进来的onFulfilled方法
          setTimeout(() => {
            // START⭐️⭐️修改⭐⭐️---------------捕获错误
            try {
              parse(p, onFulfilled(this.result), resolve, reject, 'resolve')
            } catch (error) {
              reject(error)
            }
            // END⭐️⭐️修改⭐⭐️---------------捕获错误
          });
        }
        if (this.state === 'rejected') { // reject后,状态为rejected,执行传进来的onRejected方法
          setTimeout(() => {
            // START⭐️⭐️修改⭐⭐️---------------捕获错误
            try {
              parse(p, onRejected(this.result), resolve, reject, 'reject')
            } catch (error) {
              reject(error)
            }
            // END⭐️⭐️修改⭐⭐️---------------捕获错误
          });
        }
      })
      return p
    }
    // START⭐️⭐️修改⭐⭐️---------------新增catch方法捕获错误
    // catch方法只有一个参数用于处理错误的情况
    this.catch = onRejected => {
      return this.then(null, onRejected)
    }
    // END⭐️⭐️修改⭐⭐️---------------新增catch方法捕获错误
    // 执行executor方法时有可能new Promise里面执行出错的时候,这里需要try catch
    try {
      executor(resolve, reject) // 此处执行new Promise时里面执行 resolve 或 reject 方法
    } catch (error) {
      reject(error) // new Promise 里方法报错时的处理
    }
  }
  window.Typromise = Typromise
})()

6.Promise.resolve 与 Promise.reject

···
Typromise.resolve = (value) => {
    return new Typromise((resolve, reject) => {
      if (value instanceof Typromise) {
        value.then(resolve, reject)
      } else {
        resolve(value)
      }
    })
}
Typromise.reject = (value) => {
    return new Typromise((resolve, reject) => {
        reject(value)
    })
}
window.Typromise = Typromise

测试结果 image.png 结论:Typromise.reject必须也是异步

Typromise.reject = (value) => {
    return new Typromise((resolve, reject) => {
        setTimeout(() => {
            reject(value)
        })
})

测试结果正常 image.png

7.Promise.all

  • 1.Promise.all(promises) 传入参数promises的必须是一个Array类型,若是string类型会直接返回,若是其他类型则报错
  • 2.Promise.all 是必须所有请求成功后才可resolve值,若有一个失败则直接reject
···
Typromise.all = (promises) => {
    return new Promise((resolve, reject) => {
      if (typeof promises === 'object' && promises instanceof Array) {
        const values = [];
        promises.forEach(promise => {
          promise.then(value => {
            values.push(value)
            if (promises.length === values.length) { // 必须全部成功才可resolve
              resolve(values)
            }
          }, reason => { // 有一个失败则直接reject
            reject(reason)
          })
        })
      } else {
        if (typeof promises === 'string') { // string类型会直接返回
          resolve(promises)
        } else {
          throw new TypeError(typeof promises + ' ' + promises + ' is not iterable (cannot read property Symbol(Symbol.iterator))')
        }
      }
   })
}
window.Typromise = Typromise

测试结果: image.png

8.Promise.race

  • 1.Promise.race(promises) 传入参数promises的必须是一个Array类型,若是string类型会直接返回,若是其他类型则报错
  • 2.Promise.race 是哪个请求成功返回较快就用哪个的值,谁先失败也结束直接用失败的结果
Typromise.race = (promises) => {
    return new Promise((resolve, reject) => {
      if (typeof promises == 'object' && promises instanceof Array) {
        const values = [];
        promises.forEach(promise => {
          promise.then(value => {
            resolve(value)
          }, reason => {
            reject(reason)
          })
        })
      } else {
        if (typeof promises == 'string') { // string类型会直接返回
          resolve(promises)
        } else {
          throw new TypeError(typeof promises + ' ' + promises + ' is not iterable (cannot read property Symbol(Symbol.iterator))')
        }
     }
  })
}
window.Typromise = Typromise

image.png

最后

以上的方式总结只是自己学习总结,有其他方式欢迎各位大佬评论
渣渣一个,欢迎各路大神多多指正,不求赞,只求监督指正( ̄. ̄)
有关文章经常被面试问到可以帮忙留下言,小弟也能补充完善完善一起交流学习,感谢各位大佬(~ ̄▽ ̄)~