谈谈你对 Promise 的理解

定义

Promise 是一种解决一步编程的方案,比其他传统方案(比如回调函数和事件)更合理和强大。它是位解决一步处理回调地狱问题而产生的。

三种状态

Promise 的三种状态有 pending (初始状态)、 fulfilled (成功状态)、 rejected (失败状态)

两个特点

  • Promise 对象的状态不受外界影响
  • 状态不可逆

三个缺点

  • 无法取消,新建后立即执行,无法中途取消
  • 如果不设置回调函数, Promise 内部抛出的错误不会反映到外部
  • 如果处于 Pending 状态时,无法得知目标进展的哪一个阶段

Promise.all

参数必须是一个数组,数组的每一项都是 Promise 实例,按照数组顺序执行输出, 如果遇到错误则直接输出错误

Promise.race

参数必须是一个数组,数组的每一项都是 Promise 实例,执行顺序是谁快就先输出谁

自己实现 Promise

// 三种状态
const PENDING = "pending";
const RESOLVE = "resolve";
const REJECT = "reject";

// 判断多个 Promise回调
function handlerPromise(result, newPromise, resolve, reject) {
  if (result === newPromise) throw new Error();
  if (
    (typeof result === "object" && result !== null) ||
    typeof result === "function"
  ) {
    try {
      const then = result.then;
	  // 如果then是一个方法则可能是一个 Promise 对象
      if (typeof then === "function") {
        then.call(
          result,
          (res) => {
            handlerPromise(res, newPromise, resolve, reject);
          },
          (err) => {
            reject(err);
          }
        );
      } else {
        resolve(result);
      }
    } catch (error) {
      reject(error);
    }
  } else {
    resolve(result);
  }
}

// 实现简单的 Promise
class MyPromise {
  status = PENDING;
  result = undefined;
  reason = undefined;
  onResolvedArr = [];
  onRejectedArr = [];

  constructor(excution) {
    const resolve = (result) => {
      if (this.status === PENDING) {
        this.result = result;
        this.status = RESOLVE;

        this.onResolvedArr.map((fn) => fn());
      }
    };

    const reject = (reason) => {
      if (this.status === PENDING) {
        this.reason = reason;
        this.status = REJECT;

        this.onRejectedArr.map((fn) => fn());
      }
    };

    try {
      excution(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }

  then(onResolved, onRejected) {
    const newPromise = new MyPromise((resolve, reject) => {
      if (this.status === RESOLVE) {
        setTimeout(() => {
          try {
            const result = onResolved(this.result);
            handlerPromise(result, newPromise, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }

      if (this.status === REJECT) {
        setTimeout(() => {
          try {
            const result = onRejected(this.reason);
            handlerPromise(result, newPromise, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }

      if (this.status === PENDING) {
        this.onResolvedArr.push(() => {
          try {
            const result = onResolved(this.result);
            handlerPromise(result, newPromise, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
        this.onRejectedArr.push(() => {
          try {
            const result = onResolved(this.reason);
            handlerPromise(result, newPromise, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      }
    });

    return newPromise;
  }
}

实现 Promise.all

// 普通 Promise.all,全部都是 resolve 则输出顺序按照参数顺序输出,如果存在 reject 则直接输出 reject
Promise.myAll = function (promises) {
  return new Promise((resolve, reject) => {
    let count = 0, result = [], len = promises.length

    promises.map((promise, i) => {
      promise.then(res => {
        count++
        result[i]=res

        if(count === len) return resolve(result)
      }, err => {
        return reject(err)
      })
    })
  })
}

实现 Promise.race

// 普通 Promise.race, 谁先输出则输出谁
Promise.myRace = function (promises) {
  return new Promise((resolve, reject) => {
    promises.forEach(promise => {
      promise.then(res => {
        return resolve(res)
      }, err => {
        return reject(err)
      })
    })
  })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值