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