由浅入深彻底了解Promise实现原理

477 阅读14分钟
const p = new Promise((resolve, reject) => {
    resolve('ok')
})
const result = p.then((value) => {
    return new Promise((resolve, reject) => {
        // 1,返回成功的promise
         //resolve('success')
        // 2, 返回失败的promise
        reject('error')
    })
})
result

前言

Promise是ES6引入的进行异步编程的新的解决方案, 从语法上来说,它就是一个构造函数,可封装异步的任务并且可以对结果进行处理,它最大的好处就是可以解决异步回调地域的问题,并且它的指定回调在进行错误处理这块要更加的灵活和方便. 它在现代的项目中, 无论是web还是app的项目当中,都应用的十分广泛.无论是前端还是后端都可以看到Promise的身影. 它也是现代面试的高频题目,所以必须掌握Promise运行的原理.如果你还对Promise的用法不了解,可以查看阮一峰老师的ES6 Promise教程

  • Promise的介绍

理解

  1. Promise是ES6规范
  2. Promise是JS进行异步编程的解决方案(旧方案是回调函数)一个异步操作并可以获取其成功/失败的结果
异步编程(旧方案回调函数)
(1)fs文件操作
require(fs).readfile('.index.html', (err, data) => {})
(2)数据库操作
(3)AJAX
$.get('server', (data) => {})
(4)定时器
setTimeout(()=>{},0)
  1. 从语法上来说, 它就是一个构造函数,
  2. 从功能上来说,Promise对象用来封装, 提供统一的接口,使得控制异步操作更加容易.
  3. Promise缺点:
  • 无法取消Promise, 一旦新建它就会立即执行, 无法中途取消.
  • 其次,如果不设置回调函数,Promise内部抛出的错误, 不会反应到外部.
  • 当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

Promise特点

1,Promise的状态
实例对象中的一个属性 [PromiseState]
对象的状态不受外界影响, Promise对象代表一个异步操作, 有三种状态

  • pending: 初始状态, 不是成功或失败状态.
  • resolved / fulfilled: 操作成功状态
  • rejected: 操作失败状态 2,Promise 对象的值
    实例对象中的另一个属性 [PromiseResult]
    保存着异步任务对象 [成功/失败] 的结果
  • resolve
  • reject 3,一旦状态改变, 就不会再变Promise对象的状态改变, 只有两种可能:
  • 从pending -> fulfilled
  • 从pending -> rejected 说明:
    一个Promise对象只能改成一次, 无论成功还是失败.
    成功的结果一般称为value, 失败的结果一般称为reason
    就算改变已经发生结果, 再对Promise对象添加回调函数, 也会立即得到这个结果.
    这与事件(Event)完全不同, 事件的特点是, 你错过了它, 再去监听, 是得不到结果的.

为何使用Promise

  1. 指定回调函数的方式更加灵活
  • 旧的,必须在启动异步任务前指定
$.get('server', (data) => {
     //执行内容
     //得先指定回调函数
})
  • Promise,启动异步任务=>返回Promise对象=>给Promise对象绑定回调函数(可以在异步任务结束后指定多个)
 var p = new Promise((resolve, reject) => {
            // 执行内容
            setTimeout(() =>{
                resolve('成功')
            })
         })
 // 在启动任务后指定回调函数
 p.then((val)=>{},(err) => {})
 .then((val) => {},(err)=>{})
 .then((val) => {},(err)=>{})
 .....
  1. 支持链式调用,解决回调地域的问题
// 回调地域
test1(...arg1) =>{
    test2(...arg2)=> {
       test3(...arg3) => {
           // 更多函数
       }
    }
}
  • 回调地域的缺点: 不便于阅读,不便于异常错误处理
  • 解决回调地域问题: Promise链式调用

Promise执行流程

1.Promise 基本执行图

  • 构造函数创建, executer执行器立即同步执行

Promise.png 2.Promise 详细执行流程图 (备注, resolved状态就是fulfilled状态)

 var p = new Promise ((resolved, rejected) =>{})
     p.then((onResolved, onRejected))
      .cacth(onRejected)

promise详细执行流程图.png 3.Promise 事件轮询执行图 (此处只提起带过, 如果你还对Event Loop事件轮询不了解, 可以查看这篇文章)

fn(resolve, reject)
var p = new Promise(fn)
var p' = p.then(onFufilled1, onRejected1)
var p" = p'.then(onFufilled2, onRejected2)
var p2 = new Promise(fn)
var p2' = p2.then(onFufilled1, onRejected1)
var p2" = p2'.then(onFufilled2, onRejected2)

9FB99BE6-0673-4F76-948F-540322674618.png

Promise基本使用

function rand (m, n) {
  return Math.ceil(Math.random()* (n-m+1)) + m-1;
}
/*Promise 形式实现
* resolve 解决   函数类型的数据
* reject  拒绝   函数类型的数据
* */
const p = new Promise(((resolve, reject) => {
  setTimeout(() => {
    const n = rand(1, 100) //获取 1-100的随机整数
    if (n < 30) {
      resolve(n) //将Promise的状态 设置为成功
    } else {
      reject(n) // 将Promise的状态 设置为失败
    }
  }, 500)
}))
p.then((value) => {
  console.log(value + '这是0-30的值')
}, (reason) => {
  console.log(reason + '这是30-90的值')
})

Promise API

1. Promis构造函数: Promise(executer){}

(1)executer函数: 执行器 (resolve, reject) =>{}
(2)resolve函数: 内部定义成功时我们调用的函数 value => {}
(3)reject函数: 内部定义失败时我们调用的函数 reason =>{}
说明: executor还会在Promise内部立即同步调用, 异步操作在执行器中执行

2. Promise.prototype.then方法: (onResolved, onRejected) =>{}

(1) onResolved函数: 成功的回调函数 (value) =>{}
(2) onRejected函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功/失败的回调, 返回一个新的Promise对象

3. Promise.prototype.catch方法(onRejected) => {}

(1) onRejected函数: 失败的回调函数 (reason) =>{}
说明: then()的语法糖, 相当于then(undefined, onRejected)

4. Promise.resolve方法 : (value) => {}

(1) value: 成功的数据或promise对象
说明:属于Promise的函数对象, 不属于实例,返回一个成功/失败的promise对象

// 如果传入的参数为非Promise类型的对象, 则返回的结果为成功promise对象
// 如果传入的参数promise对象, 则参数的结果决定了resolve的结果
const p1 = Promise.resolve(521)
const p2 = Promise.resolve(new Promise((resolve,reject) => {
    reject('失败')
}))

image.png

5. Promise.reject方法: (reject) => {}

(1) reason: 失败的原因
说明: 返回一个失败的promise对象

// 不管传入的参数是什么类型, 返回的都是失败的Promise对象
const p1 = Promise.reject(521)
const p2 = Promise.reject(new Promise((resolve,reject) => {
    resolve('成功')
}))
// 处理浏览器报错异常
p1.catch((reason) => {})
p2.catch((reason) => {})

image.png

6. Promise.all方法: (promises) => {}

  • promsies: 包含n个promises的数组
  • 返回一个新的promise
  • 全部成功, 状态才返回成功 PromiseResult结果为返回值组成的数组
  • 只要有一个失败了就直接失败, 返回最先失败的Promise的结果和状态
const p1 = new Promise((resolve,reject) => {
           setTimeout(() => {
              resolve('成功')
            }, 1000) 
})
const p2 = Promise.resolve('p2-成功')
const p3 = Promise.resolve('p3-成功')
Promise.race([p1,p2,p3])

image.png

7. Promise.race方法: (promises) => {}

(1)promises: 包含n个promises的数组
说明: 返回一个新的promise. 第一个完成的promise的结果状态就是最终的结果状态.
image.png

Promise 关键问题 (封装前必须注意的问题)

1. 如何改变Promise的状态

  • resolve(value): 如果当前是pending就会变为resolved
  • reject(reason): 如果当前是pending就会变成rejected
  • 抛出异常: 如果当前是pending就会变成rejected
    const p = new Promise((resolve, reject) => {
          // 1.resolve函数
          //resolve('ok') // pending => fulfilled(resolved)
          // 2.reject 函数
          //reject('error') // pending => rejected
          // 3. 抛出错误
           throw '出问题了'
    })

2. 一个promise指定多个成功/失败回调函数, 都会调用吗?

当promise改变为对应状态时都会调用

const p = new Promise((resolve, reject) => {
      resolve('OK')
})
p.then((value) => {
    console.log(value + '第一个回调函数')
})
p.then((value) => {
   console.log(value + '第二个回调函数')
})

3. 改变promsise状态和指定回调函数谁先谁后(执行)?

(1)都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
(2)如何先改状态再指定回调?

  • 在执行器中直接调用 resolve()/reject()
  • 延迟更长时间才调用then() (3) 什么时候才得到数据?
  • 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用,得到数据
  • 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
// 代码层面这样理解, 是resolve这个改变状态方法先执行, 还是then这个回调先执行
const p = new Promise((resolve, reject) => {
  // 1. 当是同步任务的时候, 是先改变状态, 在执行then
  // resolve('ok')
  // 2,当是异步任务的时候, 是先执行then, 再改变状态
  setTimeout(() =>{
    resolve('ok')
  })
})
p.then((value) => {
  console.log(value)
})

4. promise.then()返回新的promise的结果状态由什么决定?

  • (1)总结: 由then指定的回调函数执行的结果决定
  • (2)详细表达:
  • 如果抛出异常, 新promise变为rejected, reason为抛出的异常
  • 如果返回的是, 非promsie的任意值, 新promise变为resolved, value为返回的值
  • 如果返回的是另一个新的promise, 此promise的结果就会变成新promise的结果

image.png

5. promise如何串联多个操作任务?

  • promise的then()返回一个新的promise. 可以开成then()的链式调用
  • 通过then的链式调用串联多个同步/异步任务

6. promise异常穿透

  • 当使用promise的then链式调用时, 可以在最后指定失败的回调
  • 前面任何操作除了异常,都会传到最后的失败的回调中处理
const p = new Promise((resolve, reject) => {
    resolve('ok')
})
p.then((value) =>{
    throw '出错了'
}).then((value) =>{
    console.log(value)
}).catch((reason) => {
    // 结果输出->' 出错了'
    console.log(reason)
})

7. 中断promise链

  • 当使用promise的then链式调用时, 在中间中断, 不再调用后面的回调函数
  • 方法: 在回调函数中返回一个pedding状态的promise对象
const p = new Promise((resolve, reject) => {
    resolve('ok')
})
p.then((value) =>{
    // 中断promise链
    return new Promise((resolve, reject) => {})
}).then((value) => {
    console.log(value + '不会执行')
})

src=http___wx1.sinaimg.cn_bmiddle_005TGG6vly1fem11pwhmxj30j60j675t.jpg&refer=http___wx1.sinaimg.jpeg

Promise 自定义封装

说明:封装的思路->了解Promise的所有思想, 根据原来的Promise->实现自己的Promise

1. 初始结构搭建 (定义promise函数和原型上的then函数)

image.png

class Promise {
  constructor (executer) {
    executer()
  }
  then() {}
}

2. 实现Promise内部执行器函数调用的resolve和reject方法

class Promise {
  // 定义Promise属性
  PromiseState = 'pending'
  PromiseResult = null
  constructor (executer) {
    // 注意 [状态的值只能改变一次]
    // 改变对象的状态  [PromiseState]
    // 改变对象的值    [PromiseResult]
    let resolve = (value) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
    }

    let reject = (reason) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
    }
    // 处理抛出异常 throw
    try {
      executer(resolve, reject)
    }catch (e) {
      reject(e)
    }
  }
  then() {}
}
// new 封装的Promise
const p = new Promise((resolve, reject) => {
   resolve('ok')
  // reject('error')
  // throw '出错了'
})
console.log(p)
  • 这里看下结果, 接下来就不会每一层都看结果, 你可以尝试reject和throw输出结果

image.png

  • 输出原生Promise结果 image.png

3. 实现-同步调用then

  • 返回值是 promsie
  • 状态改变马上同步调用then()
  • 调用onResolved()和onRejected()回到函数
  • then的结果和状态 根据回调函数onResolved()和onRejected()的返回值决定
class Promise {
  // 定义Promise属性
  PromiseState = 'pending'
  PromiseResult = null
  // 构造函数上面已经实现, 这里省略, 可以查看第2点, 最后会给出全部的代码
  constructor (executer) {...}
  // 两个回调 onResolved onRejected
  then(onResolved, onRejected) {
    // then 返回一个新的promise
    return new Promise((resolve, reject) => {
      // 状态是成功
      if (this.PromiseState === 'fulfilled') {
        //传入PromiseResult  then的结果和状态  根据它的返回值决定
          let res = onResolved(this.PromiseResult)
          // 1. 返回值是Promise
          if (res instanceof Promise) {
            res.then(v =>{
              resolve(v)
            }, r => {
              reject(r)
            })
          }else {
            // 2.返回值是非Promise -> 直接返回成功
            resolve(res)
          }
      }
      // 状态是失败, 传入PromiseResult
      if(this.PromiseState === 'rejected') {
        //传入PromiseResult  then的结果和状态  根据它的返回值决定
        let res = onRejected(this.PromiseResult)
        // 1. 返回值是Promise
        if (res instanceof Promise) {
          res.then(v =>{
            resolve(v)
          }, r => {
            reject(r)
          })
        }else {
          // 2.返回值是非Promise -> 直接返回成功
          resolve(res)
        }
      }
    })
  }
}

image.png

4. 实现-异步调用then

  • 返回值是 promsie
  • promise状态为pending, 先同步执行then,将回调函数存储(存储多个, promise可以有多个回调)
  • 在异步函数执行完成以后, resolve/reject中改变状态
  • 调用存储的回调函数
  • try catch捕获错误
  • 提取funType 公共代码
class Promise {
  // 定义Promise属性
  PromiseState = 'pending'
  PromiseResult = null
  // 存储then的回调函数
  callbacks = []
  constructor (executer) {
    // 注意 [状态的值只能改变一次]
    // 改变对象的状态  [PromiseState]
    // 改变对象的值    [PromiseResult]
    let resolve = (value) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
      // 异步状态改变以后, 调用回调函数
      this.callbacks.forEach((item) =>{ item.onResolved() })
    }
    let reject = (reason) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
      // 异步状态改变以后, 调用回调函数
      this.callbacks.forEach((item) =>{ item.onRejected() })
    }
    // 处理抛出异常 throw
    try { executer(resolve, reject) }
    catch (e) { reject(e) }
  }
  // 两个回调 onResolved onRejected
  then(onResolved, onRejected) {
    // then 返回一个新的promise
    return new Promise((resolve, reject) => {
      // 提取公共代码
      let funType = (type)=>{
        try {
          let res = type(this.PromiseResult)
          if(res instanceof Promise) {
            res.then(v => { resolve(v) }, r => { reject(r) })
          } else {resolve(res) } // 返回非promise 直接返回成功
        }catch (e) {
          reject(e)
        }
      }
      // 传入PromiseResult,  then的结果和状态,根据funType的返回值决定
      // 状态是成功
      if (this.PromiseState === 'fulfilled') { funType(onResolved) }
      // 状态是失败,
      // 传入PromiseResult  
      if(this.PromiseState === 'rejected') { funType(onRejected) }
      // 状态为pending 存储onResolved和onRejected函数->到callback属性
      if(this.PromiseState === 'pending') {
        this.callbacks.push({
          onResolved: () => { funType(onResolved) },
          onRejected: () =>{ funType(onRejected) }
        })
      }

    })
  }
}

image.png

5. catch方法

  • catch方法是then的语法糖
class Promise {
  // 定义Promise属性
  PromiseState = 'pending'
  PromiseResult = null
  // 存储then的回调函数
  callbacks = []
  constructor (executer) {... }
  // 两个回调 onResolved onRejected
  then(onResolved, onRejected) { ... }
  // 增加catch方法
  catch(onRejected) {
    return this.then(undefined, onRejected)
  }
}

image.png

6. 异常穿透和值传递

  • 可以允许不传onResolved/onRejected实参
  • 实现: 不传参数时,内部定义一个函数
if (typeof onResolved !== 'function') {
// 成功 函数没有定义时, 直接传值
  onResolved = value => value

}
if(typeof onRejected !== 'function') {
 // 失败 函数没有定义时, 直接抛出错误
  onRejected = (reason) =>{
    throw reason
  }
}

7. then回调函数异步执行

  • then方法是异步执行的, 得等同步代码执行完以后
  • 左侧代码是我们封装的, 右侧是原生的Promise image.png
  • 实现自己分装的Promise可以异步执行
  • 实现方法: 在代码中,调用 onResovled和onRejected函数时, 增加setTimeout

image.png

8. 封装的Promise构造函数和原型链上then方法所有源码

class Promise {
  // 定义Promise属性
  PromiseState = 'pending'
  PromiseResult = null
  // 存储then的回调函数
  callbacks = []
  constructor (executer) {
    // 注意 [状态的值只能改变一次]
    // 改变对象的状态  [PromiseState]
    // 改变对象的值    [PromiseResult]
    let resolve = (value) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
      // 异步状态改变以后, 调用回调函数
      this.callbacks.forEach((item) =>{
        setTimeout(() => {
          item.onResolved()
        })
      })
    }
    let reject = (reason) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
      // 异步状态改变以后, 调用回调函数
      this.callbacks.forEach((item) =>{
        setTimeout(() => {
          item.onRejected()
        })
      })
    }
    // 处理抛出异常 throw
    try { 
      executer(resolve, reject) 
    }
    catch (e) { 
      reject(e) 
    }
  }
  // 两个回调 onResolved onRejected
  then(onResolved, onRejected) {
  // 成功 函数没有定义时, 直接传值
    if (typeof onResolved !== 'function') {
      onResolved = value => value
    }
    // 失败 函数没有定义时, 直接抛出错误
    if(typeof onRejected !== 'function') {
      onRejected = (reason) =>{
        throw reason
      }
    }
    // then 返回一个新的promise
    return new Promise((resolve, reject) => {
      // 提取公共代码
      let funType = (type)=>{
        try {
          if (typeof type !== 'function') return
          let res = type(this.PromiseResult)
          if(res instanceof Promise) {
            res.then(v => { 
              resolve(v) 
            }, r => { 
              reject(r) 
            })
          } else {// 返回非promise 直接返回成功
            resolve(res) 
          } 
        }catch (e) {
          reject(e) 
        }
      }
      // 传入PromiseResult,  then的结果和状态,根据funType的返回值决定
      // 1. 状态是成功
      if (this.PromiseState === 'fulfilled') {
        setTimeout(() => {
          funType(onResolved)
        })
      }
      // 2. 状态是失败
      if(this.PromiseState === 'rejected') {
        setTimeout(() => {
          funType(onRejected)
        })
      }
      // 状态为pending 存储onResolved和onRejected函数->到callback属性
      if(this.PromiseState === 'pending') {
        this.callbacks.push({
          onResolved: () => { funType(onResolved)},
          onRejected: () =>{ funType(onRejected) }
        })
      }
    })
  }

  catch(onRejected) {
    return this.then(undefined, onRejected)
  }
}

9. Promise函数对象->resolve方法

  • 不属于实例对象
  • 使用 static关键字声明 静态方法(属于Promise函数)
static resolve (value) {
  return new Promise((resolve, reject) =>{
    // 同then方法的判断
    if (value instanceof Promise) {
      value.then(v => {
        resolve(v)
      }, r => {
        reject(r)
      })
    } else {
      resolve(value)
    }
  })
}

10. Promise函数对象->reject方法

static reject (reason) {
  // 永远返回失败的Promise
  return new Promise((resolve, reject) => {
    reject(reason)
  })
}

11. Promise函数对象->all方法

static all (promises) {
  // 返回一个新的promise,
  // 全部成功, 状态才返回成功 PromiseResult结果为返回值组成的数组
  // 如果失败, 则返回最先失败的Promise的结果和状态
  // 按顺序存储返回的结果, 不管同步还是异步
  return new Promise((resolve, reject) => {
    let arr = []
    let num = 0
    for(let i= 0; i< promises.length; i++) {
      promises[i].then(v => {
        num++
        arr[i] = v
        // 只有当最后一个promise成功且走到这里, 代表全部成功
        if (num  ===  promises.length) {
          resolve(arr)
        }
      }, r =>{
        reject(r)
      })
    }
  })
}

12. Promise函数对象->race方法

static race (promises) {
  // 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
  return new Promise((resolve, reject) => {
    for(let i= 0; i< promises.length; i++) {
      promises[i].then( v => {
        resolve(v)
      }, r =>{
        reject(i)
      })
    }
  })
}

anync与await

anync

  • async 函数 和 Promise的then方法规则一样
  • 返回一个Promise
  • 它的结果和状态是由函数的返回值决定
async function test () {
    return 'ok'
}
test()
// test函数返回的是一个Promise

await表达式

  • await右侧表达式 一般称为Promise对象, 也可以直接是值
  • 如果表达式是Promise, 则返回的是成功的Promise的值
  • 如果表达式是其他值, 直接将此值返回
  • await 必须写在async函数中,但async函数中, 可以没有await
  • 如果await 的promise失败了,会抛出异常, 需要通过 try...catch处理

anync和await结合使用

  • Promise 实际上是利用编程技巧将回调函数改成链式调用,避免回调地狱。最大问题是代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆 then,原来的语义变得不太清楚。
  • 这里使用async和await, 语义看上去比较清晰.
// 需要在node和环境下使用
// 练习 读取one和two两个文件夹的内容
const fs = require('fs')
const util = require('util')
const mineReadFile = util.promisify(fs.readFile) // 返回一个Promise
async function readFile() {
    try{
        const d1 = await mineReadFile('./resource/one.txt')
        const d2 = await  mineReadFile('./resource/two.tx')
        console.log(d1 + d2)
    }catch (e) {
        console.log(e)
    }
}
readFile()

src=http___n.sinaimg.cn_sinacn10_480_w640h640_20180323_54aa-fysnevk9948748.jpg&refer=http___n.sinaimg.jpeg

封装Promise的代码

class Promise {
  // 定义Promise属性
  PromiseState = 'pending'
  PromiseResult = null
  // 存储then的回调函数
  callbacks = []
  constructor (executer) {
    // 注意 [状态的值只能改变一次]
    // 改变对象的状态  [PromiseState]
    // 改变对象的值    [PromiseResult]
    let resolve = (value) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
      // 异步状态改变以后, 调用回调函数
      this.callbacks.forEach((item) =>{
        setTimeout(() => {
          item.onResolved()
        })
      })
    }
    let reject = (reason) => {
      if (this.PromiseState !== 'pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
      // 异步状态改变以后, 调用回调函数
      this.callbacks.forEach((item) =>{
        setTimeout(() => {
          item.onRejected()
        })
      })
    }
    // 处理抛出异常 throw
    try {
      executer(resolve, reject)
    }
    catch (e) {
      reject(e)
    }
  }
  // 两个回调 onResolved onRejected
  then(onResolved, onRejected) {
  // 成功 函数没有定义时, 直接传值
    if (typeof onResolved !== 'function') {
      onResolved = value => value
    }
    // 失败 函数没有定义时, 直接抛出错误
    if(typeof onRejected !== 'function') {
      onRejected = (reason) =>{
        throw reason
      }
    }
    // then 返回一个新的promise
    return new Promise((resolve, reject) => {
      // 提取公共代码
      let funType = (type)=>{
        try {
          if (typeof type !== 'function') return
          let res = type(this.PromiseResult)
          if(res instanceof Promise) {
            res.then(v => {
              resolve(v)
            }, r => {
              reject(r)
            })
          } else {// 返回非promise 直接返回成功
            resolve(res)
          }
        }catch (e) {
          reject(e)
        }
      }
      // 传入PromiseResult,  then的结果和状态,根据funType的返回值决定
      // 1. 状态是成功
      if (this.PromiseState === 'fulfilled') {
        setTimeout(() => {
          funType(onResolved)
        })
      }
      // 2. 状态是失败
      if(this.PromiseState === 'rejected') {
        setTimeout(() => {
          funType(onRejected)
        })
      }
      // 状态为pending 存储onResolved和onRejected函数->到callback属性
      if(this.PromiseState === 'pending') {
        this.callbacks.push({
          onResolved: () => { funType(onResolved)},
          onRejected: () =>{ funType(onRejected) }
        })
      }
    })
  }

  catch(onRejected) {
    return this.then(undefined, onRejected)
  }

  static resolve (value) {
    return new Promise((resolve, reject) =>{
      // 同then方法的判断
      if (value instanceof Promise) {
        value.then(v => {
          resolve(v)
        }, r => {
          reject(r)
        })
      } else {
        resolve(value)
      }
    })
  }

  static reject (reason) {
    // 永远返回失败的结果
    return new Promise((resolve, reject) => {
      reject(reason)
    })
  }

  static all (promises) {
    // 返回一个新的promise,
    // 全部成功, 状态才返回成功 PromiseResult结果为返回值组成的数组
    // 如果失败, 则返回最先失败的Promise的结果和状态
    // 按顺序存储返回的结果, 不管同步还是异步
    return new Promise((resolve, reject) => {
      let arr = []
      let num = 0
      for(let i= 0; i< promises.length; i++) {
        promises[i].then(v => {
          num++
          arr[i] = v
          // 只有当最后一个promise成功且走到这里, 代表全部成功
          if (num  ===  promises.length) {
            resolve(arr)
          }
        }, r =>{
          reject(r)
        })
      }
    })
  }

  static race (promises) {
    // 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
    // 按顺序存储返回的结果, 不管同步还是异步
    return new Promise((resolve, reject) => {
      for(let i= 0; i< promises.length; i++) {
        promises[i].then( v => {
          resolve(v)
        }, r =>{
          reject(r)
        })
      }
    })
  }
}

u=3725043830,2851253220&fm=26&fmt=auto.webp