返回

挑战前端面试,解锁异步编程奥秘:Promise的进阶之旅

前端

何为Promise,一睹芳容
Promise,简单来说,就是一个承诺,一个异步操作的最终结果。它为我们提供了一种更好的方式来处理异步操作,让代码更具可读性和可维护性。

Promise的实现,揭秘黑盒

要真正理解Promise,不如亲自动手写一个符合A+规范的Promise。A+规范是Promise的一个标准,它定义了Promise应该如何工作。

class Promise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(fn => fn(this.value));
      }
    };

    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(fn => fn(this.reason));
      }
    };

    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 Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        setTimeout(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }

      if (this.state === 'rejected') {
        setTimeout(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }

      if (this.state === 'pending') {
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onFulfilled(this.value);
              resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });

        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onRejected(this.reason);
              resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
      }
    });

    return promise2;
  }
}

const resolvePromise = (promise2, x, resolve, reject) => {
  if (promise2 === x) {
    reject(new TypeError('Chaining cycle detected for promise!'));
  }

  if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
    let called = false;
    try {
      const then = x.then;
      if (typeof then === 'function') {
        then.call(
          x,
          (y) => {
            if (called) return;
            called = true;
            resolvePromise(promise2, y, resolve, reject);
          },
          (r) => {
            if (called) return;
            called = true;
            reject(r);
          },
        );
      } else {
        resolve(x);
      }
    } catch (error) {
      if (called) return;
      called = true;
      reject(error);
    }
  } else {
    resolve(x);
  }
};

Promise实战,运筹帷幄

掌握了Promise的精髓,我们来看看几个常见的面试题:

  • Promise的状态有哪些?

    • pending:等待状态
    • fulfilled:已完成状态
    • rejected:已失败状态
  • Promise的then方法的作用是什么?

    • then方法用于指定在Promise状态改变时要执行的回调函数。
  • 如果一个Promise被reject,那么它的then方法还会执行吗?

    • 不会,then方法只有在Promise被resolve时才会执行。
  • 如果一个Promise被resolve一个Promise,那么这个Promise的状态是什么?

    • 这个Promise的状态也会是resolved。
  • 如果一个Promise被resolve一个非Promise对象,那么这个Promise的状态是什么?

    • 这个Promise的状态也会是resolved。

结语

通过这篇文章,你已经掌握了Promise的精髓,并能轻松应对各种面试题。在前端面试中,Promise是必考的知识点,希望你能在面试中大放异彩,脱颖而出。