我有几个不同的JavaScript对象,我想将它们分开。但是,我需要某种类型的观察器、回调或插件设计,以便我可以在正确的时间触发这些方法。
例如,A.Foo()
几乎总是应该在B.Bar()
之后运行 - 但我不想在 B.Bar()
内部调用A.Foo()
,因为有些奇怪的时间它不应该在 B.Bar()
之后运行。那会耦合我的代码,我知道这很糟糕。
我想解决这个问题,就好像B.Bar()
只是在做它的工作,并且从不打算了解A.Foo()
或任何其他可能想要与之一起标记的功能。换句话说,为未来的开发人员提供插件支持。
如何在 Javascript 中设计带有观察者或基于事件的回调的模块化非耦合代码?
这取决于你的方案是真的像本质上的事件,还是更多的异步操作:
基于事件
使用类似微事件的东西,你可以执行以下操作。 这种模式非常常见且简单,所以我建议在某个时候你自己尝试一下,因为从理解的角度来看,这很棒。
MicroEvent.mixin(A);
A.Foo = function () {
//Do stuff A needs to do, then:
A.trigger('foo-complete');
};
//Somewhere nice and separate and decoupled
A.bind('foo-complete', B.Bar);
如果您需要执行更复杂的操作,例如过滤事件,映射事件等。 反应式扩展(基于 C# 库(非常强大,但如果不需要该功能,这是一个很大的库。
异步操作
使用回调
这可以使用回调来完成,这对于相当简单的操作非常有用:
A.Foo = function (cb) {
//Do stuff A needs to do, then:
if (cb) cb();
};
A.Foo(B.Bar);
使用承诺
这些最初看起来更复杂,但它们很容易组合,并且内置了处理错误的好方法。
使用 Q 它是更流行的 promise 库之一(同样,有很多这些(:
A.Foo = function () {
var def = Q.defer();
setTimeout(function () {
//Simulate async operation
def.resolve();
}, 1000);
return def.promise;
};
A.Foo().then(B.Bar).end();
使用控制流库
控制流库(可以说 promise 是这种情况的一个特例(旨在帮助您编写基于回调系统的操作。
Dojo 允许您侦听函数调用。
dojo.connect("foo", A, function(){
B.bar();
});