1

我正在编写一个 Javascript 库(在 Coffeescript 中),它是与服务器通信的 Comet 实现(CometD)之上的一个薄层。基本上有两种类型的事情发生:

  • 一些客户端 Javascript 代码调用library.someAction()并将操作发送到服务器;
  • 某些事件是异步发生的,library需要将此事件通知客户端代码。

这是我当前实现的代码:

https://github.com/HarvardEconCS/TurkServer/blob/master/turkserver-js-client/src/tsclient.coffee

相同的代码翻译成 Javascript: http: //pastebin.com/w4ABf1vd

对于客户端启动的操作,库中针对每种类型的操作都有一个函数。例如,有时客户端需要将测验的结果发送到服务器,所以有这个对应的功能:

  @sendQuizResults: (correct, total) =>
    @channelSend "/service/user",
      status: Codec.quizResults
      correct: correct
      total: total

对于服务器发起的事件,客户端代码需要为每种类型的事件注册一个回调,因此周围有一大堆回调和设置每个回调的函数。即,有大量以下内容:

  @requestUsername_cb = undefined

  @RequestUsername: (callback) ->
    @requestUsername_cb = callback

在上面的例子中,如果一个RequestUsername事件被触发,客户端调用requestUsername_cb()if 它存在。

这似乎开始变得一团糟,所以我想知道是否有任何好的做法可以创建这样的库,并以合理的方式组织所有事件和操作。CS 基本上将上面的所有函数都包装到一个闭包中,因此它们可以用作 JS 对象。

我不得不承认我是那些刚开始使用该语言的 Javascript 用户之一,然后出于各种原因跳入 Coffeescript。如果有什么我对 Javascript 不太了解的地方,那么我很乐意得到启发;但是,我不希望这偏离主题/变成关于 CS 与 JS 或其他东西的激烈战争。请限制您对此类 API 的一般最佳实践的回答。

4

1 回答 1

1

我认为您想要的是一些节点式事件;但是,如何设计和构建 API 通常取决于您。

Node.js 使用 EventEmitter 类处理事件。这些类具有某些事件(仅定义为字符串),以及每个事件的一组侦听器(这些只是函数)。这些事件由方法触发,并由方法emit附加on。你只需要定义一些东西来挂钩。让我们使用 EventEmitter 来定义一个这样的类。

{ EventEmitter } = require 'events'

class TurkEmitter extends EventEmitter

module.exports = new TurkEmitter

开发人员会像这样使用这个类:

TurkEmitter = require 'TurkEmitter' # Whatever path

TurkEmitter.on 'connect', (event) ->
    doSomething(with: event)

他们只是挂钩到 TurkEmitter 的'connect'事件,并且他们的函数将在该事件被触发的任何时候被调用。开发人员可以将多个侦听器附加到该事件,删除侦听器等。

在您的代码中的某处,您使用以下命令触发此事件emit

TurkEmitter.emit 'connect', { some: 'object here' } # Any object that the developer will use

似乎编写了一段代码将在客户端上运行,而一段代码将在服务器上运行。在这种情况下,您需要为客户端编写一个简单的 EventEmitter 端口。

于 2013-02-24T00:34:17.317 回答