返回

手写 Promise.all 并讲解观察者模式和发布-订阅模式

前端

引言

在现代 JavaScript 应用程序中,异步编程是必不可少的。异步编程允许我们执行耗时的操作,而不会阻塞主线程。这对于构建响应迅速且用户友好的应用程序非常重要。

Promise 是 JavaScript 中用于处理异步操作的强大工具。Promise 对象代表一个异步操作的最终完成或失败。我们可以使用 then() 方法来注册回调函数,以便在异步操作完成后执行。

Promise.all() 函数是 Promise 对象的一个静态方法。它接受一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象。新的 Promise 对象将在所有传入的 Promise 对象都完成或失败后完成。

手写 Promise.all()

为了更好地理解 Promise.all() 函数是如何工作的,我们先来手写一个简单的 Promise.all() 函数。

function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    // 存储所有 Promise 对象的结果
    const results = [];

    // 计数器,用于记录已完成的 Promise 对象的数量
    let completedCount = 0;

    // 遍历 Promise 对象数组
    for (const promise of promises) {
      // 为每个 Promise 对象添加 then() 方法
      promise.then((result) => {
        // 将结果存储在 results 数组中
        results.push(result);

        // 增加计数器
        completedCount++;

        // 如果所有 Promise 对象都已完成,则 resolve 新的 Promise 对象
        if (completedCount === promises.length) {
          resolve(results);
        }
      }).catch((error) => {
        // 如果任何一个 Promise 对象失败,则 reject 新的 Promise 对象
        reject(error);
      });
    }
  });
}

观察者模式

观察者模式是一种设计模式,它允许对象之间进行一对多的依赖关系。当一个对象(称为被观察者)发生变化时,所有依赖它的对象(称为观察者)都会收到通知。

在 JavaScript 中,我们可以使用事件监听器来实现观察者模式。例如,我们可以创建一个名为 EventEmitter 的类,它可以发出事件。然后,我们可以创建多个观察者对象,这些观察者对象可以监听 EventEmitter 对象发出的事件。当 EventEmitter 对象发出事件时,所有观察者对象都会收到通知。

class EventEmitter {
  constructor() {
    this.listeners = {};
  }

  on(eventName, listener) {
    if (!this.listeners[eventName]) {
      this.listeners[eventName] = [];
    }

    this.listeners[eventName].push(listener);
  }

  emit(eventName, data) {
    if (this.listeners[eventName]) {
      for (const listener of this.listeners[eventName]) {
        listener(data);
      }
    }
  }
}

const emitter = new EventEmitter();

emitter.on('event1', (data) => {
  console.log(`Received event1 with data: ${data}`);
});

emitter.on('event2', (data) => {
  console.log(`Received event2 with data: ${data}`);
});

emitter.emit('event1', 'Hello world!');
emitter.emit('event2', 42);

发布-订阅模式

发布-订阅模式是一种消息传递模式,它允许对象之间进行一对多的通信。发布者对象可以将消息发布到主题,订阅者对象可以订阅这些主题。当发布者对象将消息发布到主题时,所有订阅了该主题的订阅者对象都会收到该消息。

在 JavaScript 中,我们可以使用事件监听器来实现发布-订阅模式。例如,我们可以创建一个名为 PubSub 的类,它可以管理主题和订阅者。发布者对象可以将消息发布到主题,订阅者对象可以订阅这些主题。当发布者对象将消息发布到主题时,所有订阅了该主题的订阅者对象都会收到该消息。

class PubSub {
  constructor() {
    this.topics = {};
  }

  publish(topic, data) {
    if (this.topics[topic]) {
      for (const subscriber of this.topics[topic]) {
        subscriber(data);
      }
    }
  }

  subscribe(topic, listener) {
    if (!this.topics[topic]) {
      this.topics[topic] = [];
    }

    this.topics[topic].push(listener);
  }
}

const pubsub = new PubSub();

pubsub.subscribe('topic1', (data) => {
  console.log(`Received message from topic1: ${data}`);
});

pubsub.subscribe('topic2', (data) => {
  console.log(`Received message from topic2: ${data}`);
});

pubsub.publish('topic1', 'Hello world!');
pubsub.publish('topic2', 42);

结语

在本文中,我们手写了一个 Promise.all() 函数,并详细讲解了观察者模式和发布-订阅模式。这些模式对于理解 JavaScript 中的异步编程非常重要。我们还提供了