手写 Promise-3

版本3 实现Promise的then链的功能

我们先看一下es6给我们提供的Promise关于then链的特点

Promise的链式调用问题
1.如果then方法中(成功或者失败函数)返回的不是一个promise,会将这个值传递给外层下一次then的成功结果,如果没有返回值,默认返回undefined。
2.如果执行then方法中的方法(成功或者失败函数)出错了,抛出异常,会走到下一次then的失败中。
3.如果返回的是一个promise,如果返回的是一个成功的promise会走到下一次then成功的回调函数中,如果返回的是一个失败的promise会走到下一次then失败的回调函数中。会用这个promise的结果做为下一次then的成功或者失败。
总结:Promise 什么时候当前then走完了会走到下一次then的失败中去
1) 出错或者手动抛出异常会走失败
2) 返回的 Promise 出错
除了以上两点之外都走到下一次then的成功中去。

then() 方法为什么可以链式调用,因为每次调用then都返回一个新的 Promise

catch 就是then的别名,没有成功的回调只有失败的回调(错误处理: 找最近的优先处理,处理不了找下一层)

问题1:如果我有10个then,第一个出错了,会一直走剩下的9个吗?
答:那就看你有没有捕获异常,如果你有捕获异常,会接着往下走,如果你一个捕获异常都没有会跳过剩下的9个then,找到最后面的,如果还没有捕获异常就报错说你没有处理异常。就是一句话:你错误处理了接着走正常的,错误没有处理则报错。

回顾了es6提供的Promise给我们提供的then链的特点之后,我们实现一个自己的Promise的then链功能、

promise.js文件代码

const Promise = require('./3-promise.js')
const p = new Promise((resolve, reject) => {

  console.log('默认执行');
  setTimeout(() => {
    reject('失败了')
  }, 2000)
  // resolve('成功了')
})
p.then((value) => {
  console.log('s1', value);
  return 100;
}, (reason) => {
  console.log('f1', reason);
  return 200;
}).then((value) => {
  console.log('s2', value);
}, (reason) => {
  console.log('f2', reason);
})

3-promise.js文件代码(关键)

// 新增Promise then链的功能
const STATUS = {
  PENDING: 'PENDING',
  FULFILLED: 'FULFILLED',
  REJECTED: 'REJECTED'
}
class Promise {
  constructor(executor) { // constructor是类的构造函数
    this.status = STATUS.PENDING;
    this.value = null;
    this.reason = null;
    this.onResolvedCallbacks = []; // 存放成功的回调的 
    this.onRejectedCallbacks = []; // 存放失败的回调的
    const resolve = (value) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.FULFILLED;
        this.value = value;
        this.onResolvedCallbacks.forEach(fn => fn()) // 发布
      }
    }
    const reject = (reason) => {
      if (this.status === STATUS.PENDING) {
        this.status = STATUS.REJECTED;
        this.reason = reason;
        this.onRejectedCallbacks.forEach(fn => fn()) // 发布
      }
    }
    try {
      executor(resolve, reject);
    } catch(error) {
      reject(error);
    }
  }
  then(onFulfilled, onRejected) {
    let promise2 = new Promise((resolve, reject) => {
    
      if (this.status === STATUS.FULFILLED) {
        try {
          let x = onFulfilled(this.value);
          resolve(x);
        } catch(error) {
          reject(error);
        }
      }

      if (this.status === STATUS.REJECTED) {
        try {
          let x = onRejected(this.reason);
          resolve(x);
        } catch(error) {
          reject(error);
        }
      }

      if (this.status === STATUS.PENDING) {
        this.onResolvedCallbacks.push(() => {
          try {
            let x = onFulfilled(this.value)
            resolve(x)
          } catch(error) {
            reject(error)
          }
        })

        this.onRejectedCallbacks.push(() => {
          try {
            let x  = onRejected(this.reason)
            resolve(x)
          } catch(error) {
            reject(error)
          }
        })
      }
    })
    return promise2
  }
}

module.exports = Promise;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值