3

我有几个不同的 JavaScript 对象,它们的方法要分开。但是,我需要某种类型的观察者、回调或插件设计,以便我可以在正确的时间触发这些方法。

例如,A.Foo()应该几乎总是在后面 B.Bar()运行- 但我不想打电话到 A.Foo() 里面 B.Bar(),因为有些奇怪的时间它不应该在后面运行B.Bar()。那将耦合我的代码,我知道这很糟糕。

我想处理这个问题,就好像B.Bar()只是在做它的工作,并且不打算知道A.Foo()或任何其他可能想要标记的功能。换句话说,为未来的开发者提供插件支持。

您如何在 Javascript 中设计带有观察者或基于事件的回调的模块化、非耦合代码?

4

2 回答 2

2

这取决于您的场景是真正的事件,还是更多的异步操作:

基于事件

使用诸如微事件之类的东西,可以执行以下操作。这种模式非常常见且简单,因此我建议您在某些时候自己尝试一下,因为从理解的角度来看它很棒。

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 的一个特例)旨在帮助您编写基于回调系统的操作。

于 2012-08-28T17:17:14.223 回答
0

Dojo 允许您收听函数调用。

dojo.connect("foo", A, function(){
  B.bar();
});
于 2012-09-03T11:43:13.797 回答