我正在编写一个 Javascript 库(在 Coffeescript 中),它是与服务器通信的 Comet 实现 (CometD) 上的一个薄层。基本上有两种类型的事情发生:
- 某些客户端 Javascript 代码调用
library.someAction()
并将操作发送到服务器; - 某些事件是异步发生的,
库
需要将此事件通知客户端代码。
这是我当前实现的代码:
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()
(如果存在)。
这似乎开始变得一团糟,所以我想知道是否有任何好的实践来创建这样的库,并以合理的方式组织所有事件和操作。 CS 基本上将上述所有函数包装到一个闭包中,以便它们可以用作 JS 对象。
我必须承认我是那些刚刚开始使用该语言的 Javascript 用户之一,然后由于各种原因跳入了 Coffeescript。如果我对 Javascript 有什么不太理解的地方,那么我很乐意得到启发;然而,我不希望这偏离主题/变成一场关于 CS 与 JS 或其他东西的激烈 war 。请限制您对此类 API 的一般最佳实践的回答。
最佳答案
我认为你想要的是一些节点风格的事件;但是,如何设计和构建 API 通常取决于您。
Node.js 使用 EventEmitter 类处理事件。这些类具有某些事件(仅定义为字符串),以及每个事件的一组监听器(这些只是函数)。这些事件由方法 emit
触发,并通过方法 on
附加。您只需要定义一些要 Hook 的东西。让我们使用 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 端口。
关于javascript - 如何设计具有多个回调的 Javascript 库 API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15044467/