在 Javascript 中实现解耦代码/回调的正确方法是什么?



我有几个不同的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();
});

相关内容

最新更新