推荐一个写Promise的规范文档:Promises/A+
开始实现简单版本的promise:
- const PENDING = 'pending'
- const FULFILLED = 'fulfilled'
- const REJECTED = 'rejected'
- class Promise {
- constructor(excuctor) {
- this.status = PENDING;
- this.value = undefined; // 存放成功的值
- this.reason = undefined; // 存放失败的值
- this.fulfillCallbacks = [];
- this.rejectCallbacks = [];
- let resolve = (value) => {
- // 只有状态是等待的时候才可以转换成其他状态
- if (this.status === PENDING) {
- this.status = FULFILLED;
- this.value = value;
- this.fulfillCallbacks.forEach(fn => fn())
- }
- }
- let reject = (reason) => {
- if (this.status === PENDING) {
- this.status = REJECTED;
- this.reason = reason;
- this.rejectCallbacks.forEach(fn => fn())
- }
- }
- try {
- excuctor(resolve, reject)
- } catch (error) {
- reject(error)
- }
- }
- then(onFulfilled, onRejected) {
- // 同步
- if (this.status === FULFILLED) {
- return onFulfilled(this.value)
- }
- // 同步
- if (this.status === REJECTED) {
- return onRejected(this.reason)
- }
- // 异步
- if (this.status === PENDING) {
- this.fulfillCallbacks.push(() => {
- onFulfilled(this.value)
- })
- this.rejectCallbacks.push(() => {
- onRejected(this.reason)
- })
- }
- }
- }
- module.exports = Promise
上面的实现并没有考虑then的回调中返回promise的情况,所以下面的代码会着重实现这一块逻辑
1.如果then的成功或者失败回调中返回的还是promise,会等待这个promise执行结果 并将结果传给下一个then的成功时的参数中
2.只有两种情况会走下一个then的失败回调:
1.如果then的成功或者失败回调抛出异常 则走下一个then的失败回调
2.如果then的成功或者失败回调返回一个失败的promise
- const PENDING = 'pending'
- const FULFILLED = 'fulfilled'
- const REJECTED = 'rejected'
- //核心方法
- function resolvePromise(promise2, x, resolve, reject) {
- if (x === promise2) {
- return reject(new TypeError('x 不能等于 promise2'))
- }
- if (typeof x === 'object' && x !== null) {
- try {
- let then = x.then; // 取then的时候可能发生异常 别人用Object.defineProperty定义的
- if (typeof then === 'function') {
- // 确定x是promise,然后执行这个promise
- // then.call的方式可以减少再次取x.then的值 因为可能再次取会出现问题
- then.call(x, (y) => {
- // y可能还会是promise
- // resolvePromise(promise2, y, resolve, reject) resolve的时候已经判断了
- resolve(y)
- }, (r) => {
- reject(r)
- })
-
- } else {
- // x是普通值
- resolve(x)
- }
- } catch (error) {
- reject(error)
- }
- } else {
- resolve(x)
- }
- }
- class Promise {
- constructor(excuctor) {
- this.status = PENDING;
- this.value = undefined;
- this.reason = undefined;
- this.fulfillCallbacks = [];
- this.rejectCallbacks = [];
- let resolve = (value) => {
- // 如果value是一个promise
- if (value instanceof Promise) {
- return value.then(resolve, reject)
- }
- // 只有状态是等待的时候才可以转换成其他状态
- if (this.status === PENDING) {
- this.status = FULFILLED;
- this.value = value;
- this.fulfillCallbacks.forEach(fn => fn())
- }
- }
- let reject = (reason) => {
- if (this.status === PENDING) {
- this.status = REJECTED;
- this.reason = reason;
- this.rejectCallbacks.forEach(fn => fn())
- }
- }
- try {
- excuctor(resolve, reject)
- } catch (error) {
- reject(error)
- }
- }
- // x 是当前then的成功或者失败回调的返回结果
- // 如果x是普通值 直接传递到下一个then中
- // 如果x是promise 需要拿到这个promise的状态
- // 执行时抛出错误直接 调用promise2的reject
- then(onFulfilled, onRejected) {
- onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
- onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
- // 每次调用then都需要返回一个新的实例 保证状态不影响
- let promise2 = new Promise((resolve, reject) => {
- // 同步
- if (this.status === FULFILLED) {
-
- setTimeout(() => {
- try {
- let x = onFulfilled(this.value)
- // resolvePromise 判断x是普通值还是promise 然后做一些操作
- resolvePromise(promise2, x, resolve, reject)
- // resolve(x) // 这种只能处理x是普通值的情况
- } catch (error) {
- reject(error)
- }
- });
-
- }
- // 同步
- if (this.status === REJECTED) {
- setTimeout(() => {
- try {
- let x = onRejected(this.reason)
- resolvePromise(promise2, x, resolve, reject)
- } catch (error) {
- reject(error)
- }
- });
-
- }
- // 异步
- if (this.status === PENDING) {
- this.fulfillCallbacks.push(() => {
-
- setTimeout(() => {
- try {
- let x = onFulfilled(this.value)
- resolvePromise(promise2, x, resolve, reject)
- } catch (error) {
- reject(error)
- }
- });
-
- })
- this.rejectCallbacks.push(() => {
- setTimeout(() => {
- try {
- let x = onRejected(this.reason)
- resolvePromise(promise2, x, resolve, reject)
- } catch (error) {
- reject(error)
- }
- });
-
- })
- }
- })
- return promise2
- }
- }
- module.exports = Promise
promise的常用静态方法和原型方法的实现:
- static reject(error) {
- return new Promise((resolve, reject) => {
- reject(error)
- })
- }
- static resolve(value) {
- return new Promise((resolve, reject) => {
- resolve(value)
- })
- }
-
- static all(promises) {
- return new Promise(function (resolve, reject) {
- let results = [];
- let j = 0;
- let promisesLength = promises.length;
- for (let i = 0; i < promisesLength; i++) {
- Promise.resolve(promises[i]).then(res => {
- results[i] = res;
- // 当所有函数都正确执行了,resolve输出所有返回结果。
- if (++j === promisesLength) {
- resolve(results);
- }
- }, reject);
- }
- });
-
- }
-
- static race(promises) {
- return new Promise((resolve, reject) => {
- for (let promise of promises) {
- Promise.resolve(promise).then(resolve, reject)
- }
- })
- }
-
- static allSettled(promises) {
- return new Promise((resolve) => {
- let results = []
- let index = 0;
- for (let i = 0; i < promises.length; i++) {
- Promise.resolve(promises[i]).then((val) => {
- results[i] = { status: FULFILLED, value: val }
- if (++index === promises.length) { resolve(results) }
- }, err => {
- results[i] = { status: REJECTED, reason: err }
- if (++index === promises.length) { resolve(results) }
- })
- }
- })
- }
-
- static any(promises) {
- return new Promise((resolve, reject) => {
- let index = 0;
- let reasons = []
- for (let i = 0; i < promises.length; i++) {
- Promise.resolve(promises[i]).then(resolve, (err) => {
- reasons[i] = err
- if (++index === promises.length) {
- reject(new AggregateError(reasons))
- }
- })
- }
- })
- }
- finally(callback) {
- return this.then((val) => {
- // callback()
- // return val
- // Promise.resolve具备等待效果
- return Promise.resolve(callback()).then(() => val)
- }, (err) => {
- return Promise.resolve(callback()).then(() => {
- throw err
- })
-
- })
- }
- catch(errCallback) {
- return this.then(null, errCallback)
- }