JavaScript ------ Promise原理及简单实现

在ES6中推出了新的类方法,用于解决跨域之间的参数传递----Promise。

       Promise的创建时需要传入两个回调函数(ResolveReject),并且函数在Promise对象被创建时立马调用,当程序代码运行结果满足预设的条件时,回调Resolve方法,当程序代码的运行结果不满足预设条件时,回调Reject方法返回Promise对象,对象中有then、catch、finally方法,当用户对Promise对象调用then方法时,传入两个回调函数,第一个回调函数对应Promise内Resolve函数被调用时执行,第二个函数对应Promise内Reject函数被调用时执行,同时调用then方法时返回新的Promise对象,对应回调函数的返回值赋值给新Promise对象的value,实现链式调用,若在then链式前Promise对象的Reject函数被调用,则将Promise的状态交由then新返回的Promise管理。

      同时Promise还提供了Catch方法,用于捕获Reject被调用时回调的方法,同时返回新的Promise对象,并将回调函数执行的结果传递给新Promise对象的value,如果then中有对Reject函数进行了回调,则catch方法不会执行回调函数。

       Promise中还提供了Finally方法,无论Promise中的then、catch方法执行的结果如何,都会调用的方法,同时返回新的Promise对象,将finally中函数执行的结果传递给新Promise的value,实现链式调用。

       根据Promise的功能特性,手实现简单的Promise。

// 了解Promise的3个状态  pending、fulfilled、reject
const PROMISE_STATUS_PENDING = 'PROMISE_STATUS_PENDING';
const PROMISE_STATUS_FULFILLED = 'PROMISE_STATUS_FULFILLED';
const PROMISE_STATUS_REJECT = 'PROMISE_STATUS_REJECT';

// 状态错误捕获
function executorWithErr(executor, value, resolve, reject) {
  try {
    const result = executor(value);
    resolve(result);
  } catch (error) {
    reject(error)
  }
}

class WtPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING;
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledFns = [];
    this.onRejectFns = [];

    // Fulfilled状态执行
    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        // 添加微任务,获取回调方法
        queueMicrotask(() => {
          if (this.status != PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_FULFILLED;
          this.value = value;
          this.onFulfilledFns.forEach(fn => fn(value))
        })

      }
    }
    // Reject状态执行
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        queueMicrotask(() => {
          if (this.status != PROMISE_STATUS_PENDING) return
          this.status = PROMISE_STATUS_REJECT;
          this.reason = reason;
          this.onRejectFns.forEach(fn => fn(reason))
        })
      }
    }

    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  // 调用then方法,返回新promise
  then(onFulfilled, onReject) {
    const defaultReject = err => {
      throw err
    };
    onReject = onReject || defaultReject;
    const defaultonFulfilled = value => {
      return value
    };
    onFulfilled = onFulfilled || defaultonFulfilled;

    return new WtPromise((resolve, reject) => {
      if (this.status !== PROMISE_STATUS_PENDING) {
        if (onFulfilled) executorWithErr(onFulfilled, this.value, resolve, resolve);
        if (onReject) executorWithErr(onReject, this.reason, resolve, resolve);
      }
      if (this.status === PROMISE_STATUS_PENDING && onFulfilled) {
        this.onFulfilledFns.push(() => {
          executorWithErr(onFulfilled, this.value, resolve, reject)
        })
      }
      if (this.status === PROMISE_STATUS_PENDING && onReject) {
        this.onRejectFns.push(() => {
          executorWithErr(onReject, this.reason, resolve, reject)
        })
      }
    })
  }

  catch (onReject) {
    return this.then(undefined, onReject)
  };

  finally(onfinally) {
    this.then(() => {
      onfinally()
    }, () => {
      onfinally()
    })
  }

  static resolve(value) {
    return new WtPromise(resolve => resolve(value))
  }

  static reject(reason) {
    return new WtPromise((resolve, reject) => reject(reason))
  }

  static all(...promises) {
    // 有reject被调用则直接调用reject方法,否则需等待所有的Resolve执行后在执行Resolve
    return new WtPromise((resolve, reject) => {
      const values = [];
      promises.forEach(promise => {
        promise.then(value => {
          values.push(value);
          if (values.length === promises.length) {
            resolve(values)
          }
        }, err => {
          reject(err)
        })
      })
    })
  }

  static allSelter(...promises) {
    return new WtPromise((resolve, reject) => {
      const reslult = [];
      promises.forEach(promise => {
        promise.then(value => {
          reslult.push({
            status: PROMISE_STATUS_FULFILLED,
            value: value
          });
          if (reslult.length === promises.length) {
            resolve(reslult)
          }
        }, err => {
          reslult.push({
            status: PROMISE_STATUS_REJECT,
            value: err
          });
          if (reslult.length === promises.length) {
            resolve(reslult)
          }
        })
      })
    })
  }
  // 竞赛输出
  static race(...promises) {
    return new WtPromise((resolve, reject) => {
      promises.forEach(promise => {
        promise.then(res => {
          resolve(res)
        }, err => {
          reject(err)
        })
      })
    })
  }
  // 等待正确输出,否则错误集合.errors
  static any(...promises) {
    return new WtPromise((resolve, reject) => {
      const errs = [];
      promises.forEach(promise => {
        promise.then(res => {
          resolve(res)
        }, err => {
          errs.push(err);
          if (errs.length === promises.length) {
            reject(new AggregateError(errs))
          }
        })
      })
    })
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Promise是一种用于处理异步操作的JavaScript对象。它提供了一种更优雅和可读性更高的方式来处理异步代码,避免了回调地狱的问题。Promise有三个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当Promise的状态发生改变时,会触发相应的回调函数。 以下是一个简单Promise实现原理的例子: ```javascript class MyPromise { constructor(executor) { this.status = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.status === 'pending') { this.status = 'fulfilled'; this.value = value; this.onResolvedCallbacks.forEach((callback) => callback()); } }; const reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach((callback) => callback()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason; }; const promise2 = new MyPromise((resolve, reject) => { if (this.status === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.status === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.status === 'pending') { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); return promise2; } resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise')); } if (x instanceof MyPromise) { x.then(resolve, reject); } else { resolve(x); } } catch(onRejected) { return this.then(null, onRejected); } } ``` 这个例子展示了一个简单Promise实现,包括Promise的构造函数、状态的改变、回调函数的执行、链式调用以及错误处理等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

David_leil

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值