2013-02-27 84 views
2

所以我在Node.js中开始了一个小项目来学习一些。这是一个简单的缓存代理arch Linux的包系统,因为节点提供了大部分繁重的工作。在node.js中与异步同步搏斗

这有两个“主”阶段,服务器设置和服务。 然后服务有两个主要阶段,响应设置和响应。

“主”设置涉及检查一些文件,从文件加载一些配置。从网址加载一些json。然后用此信息启动http服务器和代理实例。

  • 安装记录仪/选项 - 读取配置 - 看镜子 - 读webmirror
  • 开始服务

发球涉及检查的要求,以查看是否存在该文件,创建目录如果需要的话,则提供响应。

  • 检查请求 - 查询目录 - 检查文件
  • 代理请求或服务文件

我一直都对他们的同步点,但搜索不会导致许多成果。在流程完成下一步之前必须完成一组异步任务的点。 Perl's AnyEvent has conditional variables,我猜是我想要做的,没有阻塞。

首先,我发现我是“作弊”和使用提供的任何功能的同步版本,但必须停止与Web请求,所以我开始重组的东西。立即大多数搜索导致使用异步或step来控制流量。首先,我尝试了大量的系列/并行设置,但是如果在函数下面有任何异步调用会立即“完成”并且系列完成,那么会遇到问题。

经过多次哀嚎和咬牙切齿之后,我最终用了一个“服务员”功能,使用async。直到测试某个程序状态,以便在启动下一个功能之前完成所有任务的设置。

// wait for "test" to be true, execute "run", 
// bail after "count" tries, waiting "sleep" ms between tries; 
function waiter(test, run, count, sleep, message) { 
    var i=0; 
    async.until( 
     function() { 
      if (i > count) { return true; } 
      logger.debug('waiting for',message, test()); 
      return test(); 
     }, 
     function (callback) { 
      i++; 
      setTimeout(callback, sleep); 
     }, 
     function (err) { 
      if (i > count) { 
       logger.error('timeout for', message, count*sleep); 
       return; 
      } 
      run() 
     } 
    ); 
} 

它给我的印象是相当大的和丑陋和需要的模块来实现的东西,我认为是标准的,所以我想知道什么是更好的方法。我还在用非异步的方式思考?我忽略了节点中有没有简单的东西?有没有这样做的标准方式?

我想象一下这个设置,如果程序变得复杂,将会有很多嵌套函数来描述程序的流程,我正在努力寻找一种很好的方法来完成这一切。

任何提示将不胜感激。

回答

3

你不能真的让所有东西都是同步的。 Nodejs被设计为异步执行(这当然可能会折磨你)。但也有一些方法技巧,使其以同步的方式工作(提供的伪代码是经过深思熟虑和代码都经过精心设计):

  • 使用回调
  • 使用事件
  • 使用承诺

回调和事件易于使用和理解。但有了这些,有时代码可能会变得非常混乱,难以调试。

但有了承诺,你可以避免所有这一切。您可以创建依赖链,称为'promises'(例如,只有在Promise A完成时才执行Promise B)。

早期版本的node.js实现了promise。他们承诺要做一些工作,然后分别执行回调,以执行成功和失败以及处理超时。

但在更高版本中,已删除。通过从核心node.js中删除它们,它创建了可以构建模块的可能性,这些模块具有可以位于核心之上的承诺的不同实现。其中一些是node-promise,futurespromises

看到这些链接,了解更多信息:

+0

OK,承诺,现在我有话要搜索的内容。任何想法为什么节点删除它们? – Matt 2013-02-27 19:41:48

+1

@mindthemonkey曾经在Node.js核心中可用的承诺是基于EventEmitter的,并没有像现代Promises/A +那样真正起作用。由于与Promises/A +类似,我认为Node不可链接,不会传播错误,并且与当前Node相比,有更详细的注册回调方法样式。 Promise/A +承诺中没有这些问题存在,但是,在我看来,这是比Node的回调更好的异步基础。 – 00dani 2013-07-24 08:56:09

+1

[Bluebird.js](http://bluebirdjs.com/),[ES6 Promises](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise)和[ES6 Promise polyfill](https://github.com/stefanpenner/es6-promise)是我3年后结束的地方。蓝鸟为主。 – Matt 2016-07-29 09:23:17