手写 Promise.all 并讲解观察者模式和发布-订阅模式
2024-02-13 10:00:07
引言
在现代 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 中的异步编程非常重要。我们还提供了