如何设计具有多个回调的Javascript库API?

如何设计具有多个回调的Javascript库API?,javascript,api,callback,coffeescript,Javascript,Api,Callback,Coffeescript,我正在编写一个Javascript库(用Coffeescript编写),它是Comet实现(CometD)上的一个薄层,用于与服务器通信。发生的事情基本上有两种: 一些客户端Javascript代码调用library.someAction()并将操作发送到服务器 某些事件是异步发生的,库需要将此事件通知客户端代码 以下是我当前实现的代码: 翻译成Javascript的代码相同: 对于客户端启动的操作,库中为每种类型的操作提供了一个函数。例如,有时客户端需要将测验结果发送到服务器,因此有相应

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

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

翻译成Javascript的代码相同:

对于客户端启动的操作,库中为每种类型的操作提供了一个函数。例如,有时客户端需要将测验结果发送到服务器,因此有相应的功能:

  @sendQuizResults: (correct, total) =>
    @channelSend "/service/user",
      status: Codec.quizResults
      correct: correct
      total: total
对于服务器启动的事件,客户端代码需要为每种类型的事件注册一个回调,因此有一大堆回调和设置它们的函数。也就是说,有一大堆如下内容:

  @requestUsername_cb = undefined

  @RequestUsername: (callback) ->
    @requestUsername_cb = callback
在上面的示例中,如果触发了
RequestUsername
事件,则客户端将调用
RequestUsername\u cb()
(如果存在)

这似乎开始变得一团糟,所以我想知道是否有什么好的做法可以创建这样一个库,并以合理的方式组织所有活动和行动。CS基本上将上面的所有函数包装成一个闭包,这样它们就可以用作JS对象


我必须承认,我是那种刚刚开始使用该语言,然后出于各种原因跳入咖啡脚本的Javascript用户之一。如果Javascript有什么我不太了解的地方,那么我会很高兴受到启发;然而,我不想让它偏离主题/变成一场关于CS vs JS或其他东西的火焰之战。请将您的答案限制在此类API的最佳实践中。

我认为您需要的是一些节点样式的事件;然而,如何设计和构造API通常取决于您

Node.js使用EventEmitter类处理事件。这些类具有特定的事件(仅定义为字符串)和每个事件的一组侦听器(这些只是函数)。这些事件通过方法
emit
触发,并通过方法
附加到
上。你只需要定义一些要连接的东西。让我们使用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端口。

我认为您需要的是一些节点样式的事件;然而,如何设计和构造API通常取决于您

Node.js使用EventEmitter类处理事件。这些类具有特定的事件(仅定义为字符串)和每个事件的一组侦听器(这些只是函数)。这些事件通过方法
emit
触发,并通过方法
附加到
上。你只需要定义一些要连接的东西。让我们使用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端口。

问题不是flame war,问题是熟悉javascript的人可能不会回答您的问题,因为他们无法阅读coffee脚本代码。因此,与直接使用javascript相比,您的问题对程序员的吸引力可能要小得多。除非它与coffeescript相关,否则我从不在cs中写js问题,因为这一点。想象一个用HAML写的HTML相关问题……没关系,我会用Javascript回答:)如果人们看不懂coffeescript,他们不会用Javascript回答你。好的,我添加了Javascript版本的代码。问题不是flame war,问题是熟悉javascript的人可能不会回答你,因为他们无法阅读咖啡脚本代码。因此,与直接使用javascript相比,您的问题对程序员的吸引力可能要小得多。除非它与coffeescript相关,否则我从不在cs中写js问题,因为这一点。想象一个用HAML写的HTML相关问题……没关系,我会用Javascript回答:)如果人们看不懂咖啡脚本,他们不会用Javascript回答你。好的,我添加了一个Javascript版本的代码。
EventEmitter=require('events')。EventEmitter
最好写成
{EventEmitter}=需要“事件”
。服务器端代码已写入。这一切都将发生在客户端。是否有任何节点或其他库可以包含在客户端JS中以实现这种功能?您可以使用EventEmitter2。这里有一个简单的js文件,您可以下载并包括(与节点和浏览器一起使用):
EventEmitter=require('events')。EventEmitter
最好写成
{EventEmitter}=require'events'
。服务器端代码已经编写好了。这一切都将发生在客户端。是否有任何节点或其他库可以包含在客户端JS中以实现这种功能