promise对象

promise对象

Promise 是异步编程的一种解决方案。里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

理解Promise

从语法上来说:Promise是一个构造函数
从功能上来说:Promise对象用来封装一个异步操作并获取其结果

状态的改变

  1. pending变为resolved
  2. pending变为rejected

只有这两种,且一个promise对象只能改变一次
无论成功或失败,都只有一个结果
成功的数据一般称为value,失败的结果一般称为reason

简单应用

// 创建一个promise对象
const p = new Promise((resolve, reject) => { // 执行器函数
  // 执行异步任务
  setTimeout(() => {
    const time = Data.now()
    if (time % 2 === 0) { // 成功则调用resolve()
      resolve('成功的数据' + time)
    } else { // 失败则调用reject()
      reject('失败的数据' + time)
    }
  }, 2000)
})

// then方法接收两个回调函数,分别对应成功和失败
p.then(
  value => {
    console.log('成功的回调函数' + value)
  },
  reason => {
    console.log('失败的回调函数' + reason)
  }
)

解决文章开始的回调地狱

// 链式调用,代码优雅了许多,层次也更佳清晰
pSetTimeout('回')
  .then(
    value => {
      console.log(value)
      return pSetTimeout('调')
    }
  )
  .then(
    value => {
      console.log(value)
      return pSetTimeout('地')
    }
  )
  .then(
    value => {
      console.log(value)
      return pSetTimeout('狱')
    }
  ).then(
    value => {
      console.log(value)
    }
  )

function pSetTimeout(str) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(str)
    }, 2000)
  })
}

如何使用Promise

静态方法

resolve(), reject()

返回一个以给定值解析后的Promise对象,分别接收成功值和失败值

// 产生一个成功值为1的promise对象
const p1 = new Promise((resolve, reject) => resolve(1))
p1.then(value => console.log(value)) // 1

// 语法糖
// 产生一个成功值为2的promise对象
const p2 = Promise.resolve(2)
p2.then(value => console.log(value)) // 2

//产生一个失败值为3的promise对象
const p3 = Promise.reject(3)
p3.then((null, reason) => console.log(reason)) // 3
p3.catch(reason => console.log(reason)) // 3
all()

参数内所有的promise对象都成功时回调成功(resolve),若有一个失败则回调失败(reject)。
成功的返回值是所有成功promise的成功值组成的数组;失败的返回值是第一个失败promise的结果

const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)

const pAll1 = Promise.all([p1, p2, p3])
const pAll2 = Promise.all([p1, p2])

pAll1.then(
  value => console.log('all onResolved()' + value),
  reason => console.log('all onRejected()' + reason)
) // 3

pAll2.then(
  value => console.log('all onResolved()' + value),
  reason => console.log('all onRejected()' + reason)
) // [1, 2]
race()

使用方法与Promise.all()相同
race顾名思义 竞速,即当中的第一个promise解决或失败,则返回这个promise的值

实例方法

then()

then()方法返回一个Promise。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。

catch()

catch()方法返回一个Promise,并且处理拒绝的情况。它的行为与调用Promise.prototype.then(undefined, onRejected)相同。

finally()

finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在then()catch()中各写一次的情况。

自定义Promise

构造函数

function MyPromise(excutor) {
  const self = this
  self.status = 'pending'
  self.data = undefined
  self.callbacks = []

  function resolve(value) {
    if (self.status === 'pending') {
      // 将状态改为resolved
      self.status = 'resolved'
      // 保存value数据
      self.data = value
      // 如果有待执行的callback函数,立即异步执行回调
      if (self.callbacks.length > 0) {
        setTimeout(() => { // 放入队列,执行所有成功的回调
          self.callbacks.forEach(callbackObj => {
            callbackObj.onResolved(value)
          })
        }, 0)
      }
    }
  }

  function reject(reason) {
    if (self.status === 'pending') {
      // 将状态改为rejected
      self.status = 'rejected'
      // 保存value数据
      self.data = reason
      // 如果有待执行的callback函数,立即异步执行回调
      if (self.callbacks.length > 0) {
        setTimeout(() => { // 放入队列,执行所有失败的回调
          self.callbacks.forEach(callbackObj => {
            callbackObj.onRejected(reason)
          })
        }, 0)
      }
    }
  }

  try {
    excutor(resolve, reject)
  } catch (error) {
    reject(error)
  }
}

then()方法

// then方法,指定成功和失败的回调函数,返回新的promise对象
MyPromise.prototype.then = function (onResolved, onRejected) {
  onResolved = typeof onResolved === 'function' ? onResolved : value => value
  // 指定默认的失败回调(实现错误/异常穿透的关键点)
  onRejected = typeof onRejected === 'function' ? onRejected : reason => {
    throw reason
  }
        
  const self = this
  return new MyPromise((resolve, reject) => {
        
    function handle(callback) {
      // 1. 如果抛出异常,return的promise就会失败,reason就是error
      // 2. 如果回调函数返回的不是promise,return的promise就会成功,value就是返回值
      // 3. 如果返回的函数是promise,return的结果就是这个promise的结果
      try {
        const result = callback(self.data)
        if (result instanceof MyPromise) {
          // result.then(
          //   value => resolve(value),
          //   reason => reject(reason)
          // )
          result.then(resolve, reject)
        } else {
          resolve(result)
        }
      } catch (error) {
        reject(error)
      }
    }
        
    if (self.status === 'pending') {
      self.callbacks.push({
        onResolved() {
          handle(onResolved)
        },
        onRejected() {
          handle(onRejected)
        }
      })
    } else if (self.status === 'resolved') {
      setTimeout(() => {
        handle(onResolved)
      })
    } else {
      setTimeout(() => {
        handle(onRejected)
      })
    }
  })
}

catch()方法

// catch方法,指定失败的回调函数,返回新的promise对象
MyPromise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected)
}

resolve()方法

// 返回指定结果的成功的promise
MyPromise.resolve = function (value) {
  return new MyPromise((resolve, reject) => {
    // 返回一个成功/失败的promise
    if (value instanceof MyPromise) { // value是promise 使用value的结果作为promise的结果
      value.then(resolve, reject)
    } else { // 若value不是promise,则成功 数据是value
      resolve(value)
    }
  })
}

reject()方法

// 返回指定结果的失败的promise
MyPromise.reject = function (reason) {
  // 返回一个失败的promise
  return new MyPromise((resolve, reject) => {
    reject(reason)
  })
}

all()方法

// 返回一个promise,当所有promise都成功时才成功
MyPromise.all = function (promises) {
  let resolveCount = 0;
  const values = new Array(promises.length)
  return new MyPromise((resolve, reject) => {
    promises.forEach((p, index) => {
      MyPromise.resolve(p).then(
        value => {
          resolveCount++
          values[index] = value
          if (resolveCount === promises.length) {
            resolve(values)
          }
        },
        reason => {
          reject(reason)
        }
      )
    })
  })
}

race()方法

// 返回一个promise,由第一个有结果的promise决定
MyPromise.race = function (promises) {
  return new MyPromise((resolve, reject) => {
    promises.forEach((p, index) => {
      MyPromise.resolve(p).then(
        value => {
          resolve(value)
        },
        reason => {
          reject(reason)
        }
      )
    })
  })
}

合并成一个ES6语法的

class MyPromise {
  constructor(excutor) {
    const self = this
    self.status = 'pending'
    self.data = undefined
    self.callbacks = []
        
    function resolve(value) {
      if (self.status === 'pending') {
        // 将状态改为resolved
        self.status = 'resolved'
        // 保存value数据
        self.data = value
        // 如果有待执行的callback函数,立即异步执行回调
        if (self.callbacks.length > 0) {
          setTimeout(() => { // 放入队列,执行所有成功的回调
            self.callbacks.forEach(callbackObj => {
              callbackObj.onResolved(value)
            })
          }, 0)
        }
      }
    }
        
    function reject(reason) {
      if (self.status === 'pending') {
        // 将状态改为rejected
        self.status = 'rejected'
        // 保存value数据
        self.data = reason
        // 如果有待执行的callback函数,立即异步执行回调
        if (self.callbacks.length > 0) {
          setTimeout(() => { // 放入队列,执行所有失败的回调
            self.callbacks.forEach(callbackObj => {
              callbackObj.onRejected(reason)
            })
          }, 0)
        }
      }
    }
        
      try {
        excutor(resolve, reject)
      } catch (error) {
        reject(error)
      }
  }
        
  // then方法,指定成功和失败的回调函数,返回新的promise对象
  then(onResolved, onRejected) {
    const self = this
    onResolved = typeof onResolved === 'function' ? onResolved : value => value
    // 指定默认的失败回调(实现错误/异常穿透的关键点)
    onRejected = typeof onRejected === 'function' ? onRejected : reason => {
      throw reason
    }
 
    return new MyPromise((resolve, reject) => {
      function handle(callback) {
        // 1. 如果抛出异常,return的promise就会失败,reason就是error
        // 2. 如果回调函数返回的不是promise,return的promise就会成功,value就是返回值
        // 3. 如果返回的函数是promise,return的结果就是这个promise的结果
        try {
          const result = callback(self.data)
          if (result instanceof MyPromise) {
            // result.then(
            //   value => resolve(value),
            //   reason => reject(reason)
            // )
            result.then(resolve, reject)
          } else {
            resolve(result)
          }
        } catch (error) {
          reject(error)
        }
      }
        
      if (self.status === 'pending') {
        self.callbacks.push({
          onResolved() {
            handle(onResolved)
          },
          onRejected() {
            handle(onRejected)
          }
        })
      } else if (self.status === 'resolved') {
        setTimeout(() => {
          handle(onResolved)
        })
      } else {
        setTimeout(() => {
          handle(onRejected)
        })
      }
    })
  }
        
  // catch方法,指定失败的回调函数,返回新的promise对象
  catch(onRejected) {
    return this.then(undefined, onRejected)
  }
        
  // 返回指定结果的成功的promise
  static resolve = function (value) {
    return new MyPromise((resolve, reject) => {
      // 返回一个成功/失败的promise
      if (value instanceof MyPromise) { // value是promise 使用value的结果作为promise的结果
        value.then(resolve, reject)
      } else { // 若value不是promise,则成功 数据是value
        resolve(value)
      }
    })
  }

  // 返回指定结果的失败的promise
  static reject = function (reason) {
    // 返回一个失败的promise
    return new MyPromise((resolve, reject) => {
      reject(reason)
    })
  }

  // 返回一个promise,当所有promise都成功时才成功
  static all = function (promises) {
    let resolveCount = 0;
    const values = new Array(promises.length)
    return new MyPromise((resolve, reject) => {
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          value => {
            resolveCount++
            values[index] = value
            if (resolveCount === promises.length) {
              resolve(values)
            }
          },
          reason => {
            reject(reason)
          }
        )
      })
    })
  }
        
  // 返回一个promise,由第一个有结果的promise决定
  static race = function (promises) {
    return new MyPromise((resolve, reject) => {
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          value => {
            resolve(value)
          },
          reason => {
            reject(reason)
          }
        )
      })
    })
  }
        
  // 返回一个promise,他在指定时间后确定结果
  static resolveDelay = function (value, time) {
    return new MyPromise((resolve, reject) => {
      setTimeout(() => {
        // 返回一个成功/失败的promise
        if (value instanceof MyPromise) { // value是promise 使用value的结果作为promise的结果
          value.then(resolve, reject)
        } else { // 若value不是promise,则成功 数据是value
          resolve(value)
        }
      }, time)
    })
  }
        
  // 返回一个promise,他在指定时间后失败
  static rejectDelay = function (reason, time) {
    // 返回一个失败的promise
    return new MyPromise((resolve, reject) => {
      setTimeout(() => {
        reject(reason)
      }, time)
    })
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值