Skip to content

第二天

ts
Function.prototype.myapply = function (context = window, args) {
  if (typeof this !== 'function') {
    throw new TypeError('not funciton')
  }
  if (arguments.length > 2) {
    throw new Error('Incorrect parameter length')
  }

  context.fn = this
  let result = context.fn(...args)
  delete context.fn
  return result
}
function adddd(a, b) {
  let c = a + b
  console.log(c)
}
let c = {}
adddd.myapply(c, [34, 344])
Function.prototype.myapply = function (context = window, args) {
  if (typeof this !== 'function') {
    throw new TypeError('not funciton')
  }
  if (arguments.length > 2) {
    throw new Error('Incorrect parameter length')
  }

  context.fn = this
  let result = context.fn(...args)
  delete context.fn
  return result
}
function adddd(a, b) {
  let c = a + b
  console.log(c)
}
let c = {}
adddd.myapply(c, [34, 344])
ts
Function.prototype.mybind = function (context, ...args) {
  if (typeof this !== 'function') {
    throw new TypeError('not funciton')
  }
  const fn = this
  const fNop = function () {}
  function fBound(...args2) {
    return fn.call(this instanceof fBound ? this : context, ...args, ...args2)
  }
  if (fn.prototype) {
    fNop.prototype = fn.prototype
  }
  fBound.prototype = new fNop()
  return fBound
}
//简介bind
Function.prototype.bind = function (context) {
  let _this = this
  let args = Array.prototype.slice.call(arguments, 1)
  return function () {
    return _this.apply(context, args)
  }
}
Function.prototype.bind = function (context, ...args) {
  let self = this //谨记this表示调用bind的函数
  let fBound = function () {
    //this instanceof fBound为true表示构造函数的情况。如new func.bind(obj)
    return self.apply(
      this instanceof fBound ? this : context || window,
      args.concat(Array.prototype.slice.call(arguments)),
    )
  }
  fBound.prototype = Object.create(this.prototype) //保证原函数的原型对象上的属性不丢失
  return fBound
}
Function.prototype.mybind = function (context, ...args) {
  if (typeof this !== 'function') {
    throw new TypeError('not funciton')
  }
  const fn = this
  const fNop = function () {}
  function fBound(...args2) {
    return fn.call(this instanceof fBound ? this : context, ...args, ...args2)
  }
  if (fn.prototype) {
    fNop.prototype = fn.prototype
  }
  fBound.prototype = new fNop()
  return fBound
}
//简介bind
Function.prototype.bind = function (context) {
  let _this = this
  let args = Array.prototype.slice.call(arguments, 1)
  return function () {
    return _this.apply(context, args)
  }
}
Function.prototype.bind = function (context, ...args) {
  let self = this //谨记this表示调用bind的函数
  let fBound = function () {
    //this instanceof fBound为true表示构造函数的情况。如new func.bind(obj)
    return self.apply(
      this instanceof fBound ? this : context || window,
      args.concat(Array.prototype.slice.call(arguments)),
    )
  }
  fBound.prototype = Object.create(this.prototype) //保证原函数的原型对象上的属性不丢失
  return fBound
}
ts
Function.prototype.mycall = function (context = window, ...args) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  context.fn = this // 给context创建一个临时的fn属性,将值设置为需要调用的函数
  const result = context.fn(...args)
  delete context.fn // 删除临时属性
  return result
}
function adddd(a, b) {
  let c = a + b
  console.log(c)
}
let c = {}
adddd.mycall(c, 45, 555)
Function.prototype.mycall = function (context = window, ...args) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  context.fn = this // 给context创建一个临时的fn属性,将值设置为需要调用的函数
  const result = context.fn(...args)
  delete context.fn // 删除临时属性
  return result
}
function adddd(a, b) {
  let c = a + b
  console.log(c)
}
let c = {}
adddd.mycall(c, 45, 555)
ts
let ary = [1, [2, [3, [4, 5]]], 6]
let str = JSON.stringify(ary)
//第一种处理
ary = str.replace(/([\[\]])/g, '')
str = '[' + str + ']'
ary = JSON.parse(str)
console.log(ary)
//第三种处理:递归处理
let result = []
let fn = function (ary) {
  for (let i = 0; i < ary.length; i++) {
    let item = ary[i]
    if (Array.isArray(ary[i])) {
      fn(item)
    } else {
      result.push(item)
    }
  }
}
//第四种处理:用 reduce 实现数组的 flat 方法
function flatten(ary) {
  return ary.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flatten(cur) : cur)
  }, [])
}
let ary = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(ary))
//第五种处理:扩展运算符
while (ary.some(Array.isArray)) {
  ary = [].concat(...ary)
}
let ary = [1, [2, [3, [4, 5]]], 6]
let str = JSON.stringify(ary)
//第一种处理
ary = str.replace(/([\[\]])/g, '')
str = '[' + str + ']'
ary = JSON.parse(str)
console.log(ary)
//第三种处理:递归处理
let result = []
let fn = function (ary) {
  for (let i = 0; i < ary.length; i++) {
    let item = ary[i]
    if (Array.isArray(ary[i])) {
      fn(item)
    } else {
      result.push(item)
    }
  }
}
//第四种处理:用 reduce 实现数组的 flat 方法
function flatten(ary) {
  return ary.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flatten(cur) : cur)
  }, [])
}
let ary = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(ary))
//第五种处理:扩展运算符
while (ary.some(Array.isArray)) {
  ary = [].concat(...ary)
}
ts
/*
 * @Author: your name
 * @Date: 2020-03-13 10:14:38
 * @LastEditTime: 2020-04-06 16:16:40
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \jstutor\js\myflatten.js
 */
let flattened = (arr) =>
  arr.reduce(
    (acc, cur) => acc.concat(Array.isArray(cur) ? flattened(cur) : cur),
    [],
  )

console.log(flattened([45, 44, [334, [555]]]))
/*
 * @Author: your name
 * @Date: 2020-03-13 10:14:38
 * @LastEditTime: 2020-04-06 16:16:40
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \jstutor\js\myflatten.js
 */
let flattened = (arr) =>
  arr.reduce(
    (acc, cur) => acc.concat(Array.isArray(cur) ? flattened(cur) : cur),
    [],
  )

console.log(flattened([45, 44, [334, [555]]]))
ts
function myinstance(left, right) {
  let proto = Object.getPrototypeOf(left)
  while (true) {
    if (proto == null) {
      return false
    }
    if (proto == right.prototype) {
      return true
    }
    proto = Object.getPrototypeOf(proto)
  }
}

function Parent(name, sex) {
  this.name = name
  this.sex = sex
}
let a = 223
let p = new Parent('hh', 'sex')
console.log(myinstance(a, Parent))
function myinstance(left, right) {
  let proto = Object.getPrototypeOf(left)
  while (true) {
    if (proto == null) {
      return false
    }
    if (proto == right.prototype) {
      return true
    }
    proto = Object.getPrototypeOf(proto)
  }
}

function Parent(name, sex) {
  this.name = name
  this.sex = sex
}
let a = 223
let p = new Parent('hh', 'sex')
console.log(myinstance(a, Parent))
ts
function myNew(fn, ...args) {
  let instance = Object.create(fn.prototype)
  let result = fn.apply(instance, args)
  return typeof result === 'object' ? result : instance
}
function myNew(fn, ...args) {
  let instance = Object.create(fn.prototype)
  let result = fn.apply(instance, args)
  return typeof result === 'object' ? result : instance
}
ts
function createNew(Con, ...args) {
  const obj = Object.create(Con.prototype)
  const ret = Con.apply(obj, args)
  return ret instanceof Object ? ret : obj
}

// 1. 将构造函数的原型赋值给新建的obj的隐式原型__proto__。
// 2. 在obj下执行构造函数,并传入参数,
//    这个时候构造函数内的this就是obj。
// 3. 如果这个'构造函数'没有return对象格式的结果,
//    返回新创建的obj。

function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.getName = function () {
  console.log(this.name)
}

const xm = createNew(Person, 'xiaoming', 22)
console.log(xm)
function createNew(Con, ...args) {
  const obj = Object.create(Con.prototype)
  const ret = Con.apply(obj, args)
  return ret instanceof Object ? ret : obj
}

// 1. 将构造函数的原型赋值给新建的obj的隐式原型__proto__。
// 2. 在obj下执行构造函数,并传入参数,
//    这个时候构造函数内的this就是obj。
// 3. 如果这个'构造函数'没有return对象格式的结果,
//    返回新创建的obj。

function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.getName = function () {
  console.log(this.name)
}

const xm = createNew(Person, 'xiaoming', 22)
console.log(xm)
ts
function Promise(excutor) {
  let self = this
  self.onResolvedCallback = []
  function resolve(value) {
    setTimeout(() => {
      self.data = value
      self.onResolvedCallback.forEach((callback) => callback(value))
    })
  }
  excutor(resolve.bind(self))
}
Promise.prototype.then = function (onResolved) {
  let self = this
  return new Promise((resolve) => {
    self.onResolvedCallback.push(function () {
      let result = onResolved(self.data)
      if (result instanceof Promise) {
        result.then(resolve)
      } else {
        resolve(result)
      }
    })
  })
}
function Promise(excutor) {
  let self = this
  self.onResolvedCallback = []
  function resolve(value) {
    setTimeout(() => {
      self.data = value
      self.onResolvedCallback.forEach((callback) => callback(value))
    })
  }
  excutor(resolve.bind(self))
}
Promise.prototype.then = function (onResolved) {
  let self = this
  return new Promise((resolve) => {
    self.onResolvedCallback.push(function () {
      let result = onResolved(self.data)
      if (result instanceof Promise) {
        result.then(resolve)
      } else {
        resolve(result)
      }
    })
  })
}
ts
const obj = {
  name: 'app',
  age: '18',
  a: {
    b: 1,
    c: 2,
  },
}
const p = new Proxy(obj, {
  get(target, propKey, receiver) {
    console.log('你访问了' + propKey)
    return Reflect.get(target, propKey, receiver)
  },
  set(target, propKey, value, receiver) {
    console.log('你设置了' + propKey)
    console.log('新的' + propKey + '=' + value)
    Reflect.set(target, propKey, value, receiver)
  },
})
p.age = '20'
console.log(p.age)
p.newPropKey = '新属性'
console.log(p.newPropKey)
p.a.d = '这是obj中a的属性'
console.log(p.a.d)
const obj = {
  name: 'app',
  age: '18',
  a: {
    b: 1,
    c: 2,
  },
}
const p = new Proxy(obj, {
  get(target, propKey, receiver) {
    console.log('你访问了' + propKey)
    return Reflect.get(target, propKey, receiver)
  },
  set(target, propKey, value, receiver) {
    console.log('你设置了' + propKey)
    console.log('新的' + propKey + '=' + value)
    Reflect.set(target, propKey, value, receiver)
  },
})
p.age = '20'
console.log(p.age)
p.newPropKey = '新属性'
console.log(p.newPropKey)
p.a.d = '这是obj中a的属性'
console.log(p.a.d)
ts
let urlStr = 'http://www.inode.club?name=koala&study=js&study=node'
// 参数转成对象
function queryString(request) {
  let params = request.split('?')[1]
  let param = params.split('&')
  let obj = {}
  for (let i = 0; i < param.length; i++) {
    let paramsA = param[i].split('=')
    let key = paramsA[0]
    let value = paramsA[1]
    if (obj[key]) {
      console.log(obj)
      obj[key] = Array.isArray(obj[key]) ? obj[key] : [obj[key]]
      obj[key].push(value)
    } else {
      obj[key] = value
    }
  }
  return obj
}
console.log(queryString(urlStr))
let urlStr = 'http://www.inode.club?name=koala&study=js&study=node'
// 参数转成对象
function queryString(request) {
  let params = request.split('?')[1]
  let param = params.split('&')
  let obj = {}
  for (let i = 0; i < param.length; i++) {
    let paramsA = param[i].split('=')
    let key = paramsA[0]
    let value = paramsA[1]
    if (obj[key]) {
      console.log(obj)
      obj[key] = Array.isArray(obj[key]) ? obj[key] : [obj[key]]
      obj[key].push(value)
    } else {
      obj[key] = value
    }
  }
  return obj
}
console.log(queryString(urlStr))
ts
const clone = (parent) => {
  // 判断类型
  const isType = (target, type) =>
    `[object ${type}]` === Object.prototype.toString.call(target)

  // 处理正则
  const getRegExp = (re) => {
    let flags = ''
    if (re.global) flags += 'g'
    if (re.ignoreCase) flags += 'i'
    if (re.multiline) flags += 'm'
    return flags
  }

  const _clone = (parent) => {
    if (parent === null) return null
    if (typeof parent !== 'object') return parent

    let child, proto

    if (isType(parent, 'Array')) {
      // 对数组做特殊处理
      child = []
    } else if (isType(parent, 'RegExp')) {
      // 对正则对象做特殊处理
      child = new RegExp(parent.source, getRegExp(parent))
      if (parent.lastIndex) child.lastIndex = parent.lastIndex
    } else if (isType(parent, 'Date')) {
      // 对Date对象做特殊处理
      child = new Date(parent.getTime())
    } else {
      // 处理对象原型
      proto = Object.getPrototypeOf(parent)
      // 利用Object.create切断原型链
      child = Object.create(proto)
    }
    for (let i in parent) {
      // 递归
      child[i] = _clone(parent[i])
    }
    return child
  }
  return _clone(parent)
}
const clone = (parent) => {
  // 判断类型
  const isType = (target, type) =>
    `[object ${type}]` === Object.prototype.toString.call(target)

  // 处理正则
  const getRegExp = (re) => {
    let flags = ''
    if (re.global) flags += 'g'
    if (re.ignoreCase) flags += 'i'
    if (re.multiline) flags += 'm'
    return flags
  }

  const _clone = (parent) => {
    if (parent === null) return null
    if (typeof parent !== 'object') return parent

    let child, proto

    if (isType(parent, 'Array')) {
      // 对数组做特殊处理
      child = []
    } else if (isType(parent, 'RegExp')) {
      // 对正则对象做特殊处理
      child = new RegExp(parent.source, getRegExp(parent))
      if (parent.lastIndex) child.lastIndex = parent.lastIndex
    } else if (isType(parent, 'Date')) {
      // 对Date对象做特殊处理
      child = new Date(parent.getTime())
    } else {
      // 处理对象原型
      proto = Object.getPrototypeOf(parent)
      // 利用Object.create切断原型链
      child = Object.create(proto)
    }
    for (let i in parent) {
      // 递归
      child[i] = _clone(parent[i])
    }
    return child
  }
  return _clone(parent)
}
ts
let throttle = function (func, delay) {
  let timer = null
  return function () {
    let context = this
    let args = arguments
    if (!timer) {
      timer = setTimeout(function () {
        func.apply(context, args)
        timer = null
      }, delay)
    }
  }
}
function handle() {
  console.log(Math.random())
}
throttle(handle, 1000)
let throttle = function (func, delay) {
  let timer = null
  return function () {
    let context = this
    let args = arguments
    if (!timer) {
      timer = setTimeout(function () {
        func.apply(context, args)
        timer = null
      }, delay)
    }
  }
}
function handle() {
  console.log(Math.random())
}
throttle(handle, 1000)
ts
let length = 10
function fn() {
  console.log(`fn中的${this.length}`)
}

let obj = {
  length: 5,
  method: function (fn) {
    fn()
    arguments[0]()
  },
}

obj.method(fn, 1) //输出是什么?
let length = 10
function fn() {
  console.log(`fn中的${this.length}`)
}

let obj = {
  length: 5,
  method: function (fn) {
    fn()
    arguments[0]()
  },
}

obj.method(fn, 1) //输出是什么?

手写promise

js
/**
 * 1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行
 * 2. executor 接受两个参数,分别是 resolve 和 reject
 * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
 * 4. promise 的状态一旦确认,就不会再改变
 * 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled,
 *      和 promise 失败的回调 onRejected
 * 6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。
 *      如果promise已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。
 *      如果promise的状态是pending,需要将onFulfilled和onRejected函数存放起来,等待状态确定后,再依次将对应的函数执行(发布订阅)
 * 7. then 的参数 onFulfilled 和 onRejected 可以缺省
 * 8. promise 可以then多次,promise 的then 方法返回一个 promise
 * 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled)
 * 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected)
 * 11.如果 then 返回的是一个promise,那么会等这个promise执行完,promise如果成功,
 *   就走下一个then的成功,如果失败,就走下一个then的失败
 */

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(executor) {
  let self = this
  self.status = PENDING
  self.onFulfilled = [] //成功的回调
  self.onRejected = [] //失败的回调
  //PromiseA+ 2.1
  function resolve(value) {
    if (self.status === PENDING) {
      self.status = FULFILLED
      self.value = value
      self.onFulfilled.forEach((fn) => fn()) //PromiseA+ 2.2.6.1
    }
  }

  function reject(reason) {
    if (self.status === PENDING) {
      self.status = REJECTED
      self.reason = reason
      self.onRejected.forEach((fn) => fn()) //PromiseA+ 2.2.6.2
    }
  }

  try {
    executor(resolve, reject)
  } catch (e) {
    reject(e)
  }
}

Promise.prototype.then = function (onFulfilled, onRejected) {
  //PromiseA+ 2.2.1 / PromiseA+ 2.2.5 / PromiseA+ 2.2.7.3 / PromiseA+ 2.2.7.4
  onFulfilled =
    typeof onFulfilled === 'function' ? onFulfilled : (value) => value
  onRejected =
    typeof onRejected === 'function'
      ? onRejected
      : (reason) => {
          throw reason
        }
  let self = this
  //PromiseA+ 2.2.7
  let promise2 = new Promise((resolve, reject) => {
    if (self.status === FULFILLED) {
      //PromiseA+ 2.2.2
      //PromiseA+ 2.2.4 --- setTimeout
      setTimeout(() => {
        try {
          //PromiseA+ 2.2.7.1
          let x = onFulfilled(self.value)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          //PromiseA+ 2.2.7.2
          reject(e)
        }
      })
    } else if (self.status === REJECTED) {
      //PromiseA+ 2.2.3
      setTimeout(() => {
        try {
          let x = onRejected(self.reason)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
    } else if (self.status === PENDING) {
      self.onFulfilled.push(() => {
        setTimeout(() => {
          try {
            let x = onFulfilled(self.value)
            resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      })
      self.onRejected.push(() => {
        setTimeout(() => {
          try {
            let x = onRejected(self.reason)
            resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      })
    }
  })
  return promise2
}

function resolvePromise(promise2, x, resolve, reject) {
  let self = this
  //PromiseA+ 2.3.1
  if (promise2 === x) {
    reject(new TypeError('Chaining cycle'))
  }
  if ((x && typeof x === 'object') || typeof x === 'function') {
    let used //PromiseA+2.3.3.3.3 只能调用一次
    try {
      let then = x.then
      if (typeof then === 'function') {
        //PromiseA+2.3.3
        then.call(
          x,
          (y) => {
            //PromiseA+2.3.3.1
            if (used) return
            used = true
            resolvePromise(promise2, y, resolve, reject)
          },
          (r) => {
            //PromiseA+2.3.3.2
            if (used) return
            used = true
            reject(r)
          }
        )
      } else {
        //PromiseA+2.3.3.4
        if (used) return
        used = true
        resolve(x)
      }
    } catch (e) {
      //PromiseA+ 2.3.3.2
      if (used) return
      used = true
      reject(e)
    }
  } else {
    //PromiseA+ 2.3.3.4
    resolve(x)
  }
}

module.exports = Promise
export {}
/**
 * 1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行
 * 2. executor 接受两个参数,分别是 resolve 和 reject
 * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
 * 4. promise 的状态一旦确认,就不会再改变
 * 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled,
 *      和 promise 失败的回调 onRejected
 * 6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。
 *      如果promise已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。
 *      如果promise的状态是pending,需要将onFulfilled和onRejected函数存放起来,等待状态确定后,再依次将对应的函数执行(发布订阅)
 * 7. then 的参数 onFulfilled 和 onRejected 可以缺省
 * 8. promise 可以then多次,promise 的then 方法返回一个 promise
 * 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled)
 * 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected)
 * 11.如果 then 返回的是一个promise,那么会等这个promise执行完,promise如果成功,
 *   就走下一个then的成功,如果失败,就走下一个then的失败
 */

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(executor) {
  let self = this
  self.status = PENDING
  self.onFulfilled = [] //成功的回调
  self.onRejected = [] //失败的回调
  //PromiseA+ 2.1
  function resolve(value) {
    if (self.status === PENDING) {
      self.status = FULFILLED
      self.value = value
      self.onFulfilled.forEach((fn) => fn()) //PromiseA+ 2.2.6.1
    }
  }

  function reject(reason) {
    if (self.status === PENDING) {
      self.status = REJECTED
      self.reason = reason
      self.onRejected.forEach((fn) => fn()) //PromiseA+ 2.2.6.2
    }
  }

  try {
    executor(resolve, reject)
  } catch (e) {
    reject(e)
  }
}

Promise.prototype.then = function (onFulfilled, onRejected) {
  //PromiseA+ 2.2.1 / PromiseA+ 2.2.5 / PromiseA+ 2.2.7.3 / PromiseA+ 2.2.7.4
  onFulfilled =
    typeof onFulfilled === 'function' ? onFulfilled : (value) => value
  onRejected =
    typeof onRejected === 'function'
      ? onRejected
      : (reason) => {
          throw reason
        }
  let self = this
  //PromiseA+ 2.2.7
  let promise2 = new Promise((resolve, reject) => {
    if (self.status === FULFILLED) {
      //PromiseA+ 2.2.2
      //PromiseA+ 2.2.4 --- setTimeout
      setTimeout(() => {
        try {
          //PromiseA+ 2.2.7.1
          let x = onFulfilled(self.value)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          //PromiseA+ 2.2.7.2
          reject(e)
        }
      })
    } else if (self.status === REJECTED) {
      //PromiseA+ 2.2.3
      setTimeout(() => {
        try {
          let x = onRejected(self.reason)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
    } else if (self.status === PENDING) {
      self.onFulfilled.push(() => {
        setTimeout(() => {
          try {
            let x = onFulfilled(self.value)
            resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      })
      self.onRejected.push(() => {
        setTimeout(() => {
          try {
            let x = onRejected(self.reason)
            resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      })
    }
  })
  return promise2
}

function resolvePromise(promise2, x, resolve, reject) {
  let self = this
  //PromiseA+ 2.3.1
  if (promise2 === x) {
    reject(new TypeError('Chaining cycle'))
  }
  if ((x && typeof x === 'object') || typeof x === 'function') {
    let used //PromiseA+2.3.3.3.3 只能调用一次
    try {
      let then = x.then
      if (typeof then === 'function') {
        //PromiseA+2.3.3
        then.call(
          x,
          (y) => {
            //PromiseA+2.3.3.1
            if (used) return
            used = true
            resolvePromise(promise2, y, resolve, reject)
          },
          (r) => {
            //PromiseA+2.3.3.2
            if (used) return
            used = true
            reject(r)
          }
        )
      } else {
        //PromiseA+2.3.3.4
        if (used) return
        used = true
        resolve(x)
      }
    } catch (e) {
      //PromiseA+ 2.3.3.2
      if (used) return
      used = true
      reject(e)
    }
  } else {
    //PromiseA+ 2.3.3.4
    resolve(x)
  }
}

module.exports = Promise
export {}

Released under the MIT License.