返回

Node.js 基础设计模式:回调模式/观察者模式

前端

引言

Node.js 是一个事件驱动的、异步的编程平台。这意味着它不使用线程来执行代码,而是使用事件循环来处理事件。当一个事件发生时,Node.js 会将它添加到事件队列中。事件循环会从队列中取出事件并执行与该事件关联的函数。

这种事件驱动的体系结构使得 Node.js 非常适合构建高性能、可扩展的应用程序。然而,它也给 Node.js 开发人员带来了新的挑战。其中一个挑战是如何处理异步代码。

回调模式

回调模式是一种常见的异步编程模式。它允许一个函数在另一个函数完成时执行。回调函数通常作为参数传递给另一个函数。当另一个函数完成时,它会调用回调函数,并把结果作为参数传递给回调函数。

例如,以下代码使用回调模式来读取一个文件:

fs.readFile('file.txt', function(err, data) {
  if (err) {
    console.error(err);
    return;
  }

  console.log(data);
});

在这个例子中,fs.readFile() 函数是异步的。它接受两个参数:一个文件名和一个回调函数。当 fs.readFile() 函数完成时,它会调用回调函数。回调函数接受两个参数:一个错误对象和一个数据对象。如果发生错误,错误对象将包含错误信息。否则,数据对象将包含文件的内容。

观察者模式

观察者模式是一种设计模式,它允许一个对象(发布者)向多个对象(订阅者)发送通知。当发布者发生变化时,它会通知所有订阅者。订阅者可以根据通知采取相应的行动。

例如,以下代码使用观察者模式来实现一个简单的聊天应用程序:

// 发布者
class Chat {
  constructor() {
    this.subscribers = [];
  }

  subscribe(subscriber) {
    this.subscribers.push(subscriber);
  }

  unsubscribe(subscriber) {
    this.subscribers = this.subscribers.filter(s => s !== subscriber);
  }

  send(message) {
    this.subscribers.forEach(subscriber => subscriber.receive(message));
  }
}

// 订阅者
class User {
  constructor(name) {
    this.name = name;
  }

  receive(message) {
    console.log(`${this.name} received: ${message}`);
  }
}

// 创建一个聊天对象
const chat = new Chat();

// 创建两个用户对象
const user1 = new User('Alice');
const user2 = new User('Bob');

// 订阅聊天对象
chat.subscribe(user1);
chat.subscribe(user2);

// 发送一条消息
chat.send('Hello, world!');

在这个例子中,Chat 类是发布者。它有一个 subscribers 数组,其中包含所有订阅者。subscribe()unsubscribe() 方法允许订阅者订阅和取消订阅聊天对象。send() 方法允许发布者向所有订阅者发送消息。

User 类是订阅者。它有一个 receive() 方法,用于接收消息。

chat 对象调用 send() 方法时,它会遍历 subscribers 数组并调用每个订阅者的 receive() 方法。这使得每个订阅者都可以收到消息并采取相应的行动。

比较

回调模式和观察者模式都是处理异步代码的常见设计模式。然而,它们之间也存在一些区别。

  • 回调模式是基于函数的,而观察者模式是基于对象的。
  • 回调模式是单向的,而观察者模式是双向的。
  • 回调模式更适合于一次性任务,而观察者模式更适合于持续性任务。

何时使用

回调模式和观察者模式都是非常有用的设计模式。然而,它们适用于不同的场景。

  • 回调模式 适用于需要在另一个函数完成时执行的场景。例如,当需要读取文件或发送网络请求时,可以使用回调模式。
  • 观察者模式 适用于需要持续通知多个对象的情况。例如,当需要实现聊天应用程序或股票市场行情更新时,可以使用观察者模式。

结论

回调模式和观察者模式都是非常有用的设计模式。了解这两种模式及其区别将有助于你编写更健壮、更可扩展的 Node.js 代码。