异步观察者模式(Async Observer Pattern)的核心思想是:
当被观察者(Subject)状态变化时,通知观察者的过程是异步的,不阻塞主流程。
下面从 设计思路 → 常见实现方式 → 代码示例(Java / JS) → 注意事项 来系统说明。
同步观察者模式的问题:
notifyObservers() 会依次调用每个观察者异步观察者模式的改进:
public interface Observer {
void update(String event);
}
import java.util.*;
import java.util.concurrent.*;
public class Subject {
private final List<Observer> observers = new ArrayList<>();
private final ExecutorService executor =
Executors.newFixedThreadPool(4);
public void addObserver(Observer observer) {
observers.add(observer);
}
public void notifyObservers(String event) {
for (Observer observer : observers) {
executor.submit(() -> {
try {
observer.update(event);
} catch (Exception e) {
// 防止单个观察者异常影响其它任务
e.printStackTrace();
}
});
}
}
public void shutdown() {
executor.shutdown();
}
}
public class LogObserver implements Observer {
@Override
public void update(String event) {
System.out.println("Log: " + event + " [" + Thread.currentThread().getName() + "]");
}
}
public class EmailObserver implements Observer {
@Override
public void update(String event) {
System.out.println("Send email: " + event);
}
}
public class Main {
public static void main(String[] args) {
Subject subject = new Subject();
subject.addObserver(new LogObserver());
subject.addObserver(new EmailObserver());
subject.notifyObservers("order_created");
subject.shutdown();
}
}
✅ 优点:
const observers = [];
function subscribe(observer) {
observers.push(observer);
}
async function notifyObservers(data) {
observers.forEach(async (observer) => {
try {
await observer(data);
} catch (e) {
console.error(e);
}
});
}
subscribe(async (msg) => {
await new Promise(r => setTimeout(r, 1000));
console.log("Log:", msg);
});
subscribe(async (msg) => {
console.log("Email:", msg);
});
notifyObservers("order_created");
class EventBus {
private final ExecutorService executor = Executors.newCachedThreadPool();
private final Map<String, List<Runnable>> subscribers = new HashMap<>();
public void subscribe(String event, Runnable task) {
subscribers.computeIfAbsent(event, k -> new ArrayList<>()).add(task);
}
public void publish(String event) {
subscribers.getOrDefault(event, List.of())
.forEach(executor::submit);
}
}
否则异步线程可能直接终止
shutdown()✅ 适合:
❌ 不适合:
异步观察者模式 = 观察者模式 + 异步执行(线程池 / 事件 / MQ)
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。