所以,我正在尝试将我的聊天系统升级到 Node.js,而且我已经好几年没觉得自己像个菜鸟了!
在 PHP 中,它效率低下,但绝对有意义。请求启动,它计算出用户信息、房间信息、解析消息等等。相当线性。它在不同的地方调用了几个函数,但每次,它只需要直接向该函数发送它需要的信息。完成该功能后,它会返回,然后使用不同的信息使用其他内容完成更多工作。如果出现异常,它(通常)会被捕获到可以提醒用户的级别。
据我了解,Node.js 绝对不是这样工作的,而是主要由回调提供支持——而且我有很多回调正在进行。它必须处理初始连接,然后它必须检查 cookie 文件是否存在,然后它必须读取 cookie 文件,然后它必须从数据库中获取一些用户信息,然后它必须获取一些来自数据库的其他用户信息,然后它必须从数据库中获取更多用户信息,然后它必须将用户添加到房间,如果一段时间内没有任何人,则必须获取从数据库中获取房间信息,然后最终响应请求。完成后,至少还有两个级别的权限检查。
它与 PHP 进程没有太大区别,但在 PHP 中,它是通过 Apache 进行多线程处理的,因此请求可以坐在那里等待 DB 调用返回而完全没有问题。用户查找、房间订阅、权限,都单独处理。
在 Node.js 中,“当你完成了那个”系统并不太难理解(我已经大量使用客户端 JS 和 jQuery),但变量传递肯定是。其中很大一部分是 try/catch 被回调彻底击败。如果房间数据查找查询失败,该函数需要知道它应该将错误发送回哪个连接(到那时可能是过去的两个或三个连接),因为它不会冒泡到多个级别返回. 因此,连接对象需要通过每个回调传递。这在处理异常时只是有点恶心,因为这些可能发生在任何地方,最后一个回调,我的手指拒绝再输入任何内容,直到我调查出了如此严重的错误!
所以我想我想知道的是,是否有任何我不熟悉的“黑客”可能允许变量“跳过”非嵌套回调。无限期地关闭 try/catch 链也很不错。
编辑:我在处理数百行代码时遇到了麻烦,所以让我们看看我是否可以通过回调堆栈提供一些视觉帮助。同一行的任何内容都是直接调用,下一行是回调。
connection.on('messaage') -> controller.validateUser -> fs.exists
fs.readFile
function() -> controller.addUser -> factory.user -> user.refreshData -> db.query
user.refreshChars -> db.query
user.refreshBlocks -> db.query
function() -> controller.addRoom -> factory.room -> room.refreshData -> db.query
room.getRole -> db.query
function() -> room.getUserList -> connection.sendUTF
如您所见,这些函数大多位于对象中,而不仅仅是嵌套的未命名函数,因为它们通常需要从多个位置以任意顺序访问。问题是,有些级别需要用户对象,有些则不需要。如果 try/catch 正常工作,则只有第一个和最后一个需要知道连接才能发回信息。
我需要的是一种为这些不同的功能提供不同信息的方法,而不必在每个功能之前用他们不需要的东西来淹没它。这是不受欢迎的做法。我还需要各种用户对象函数以非常不同的方式失败 - 对象不需要关注自身的方式,因为它是调用函数的责任。