众所周知,异步是nodejs中得天独厚的特点和优势,但同时在程序中同步的需求(比如控制程序的执行顺序为:func1 -> func2 ->func3 )也是很常见的。本文就是对这个问题记录自己的一些想法。

需要执行的函数:

 
  1. var func1 = function(req,res,callback){
  2. setTimeout(function(){
  3. console.log('in func1');
  4. callback(req,res,1);
  5. },13000);
  6. }
  7. var func2 = function(req,res,callback){
  8. setTimeout(function(){
  9. console.log('in func2');
  10. callback(req,res,2);
  11. },5000);
  12. }
  13.  
  14. var func3 = function(req,res,callback){
  15. setTimeout(function(){
  16. console.log('in func3');
  17. callback(req,res,3);
  18. },1000);
  19. }
 

可以看出在func1,func2和func3中都是用了setTimeout函数,执行的时间分别为13秒,5秒和1秒。由于nodejs异步的特性,如果使用普通的函数调用方法:

 
  1. var req = null;
  2. var res = null;
  3. var callback = function(){};
  4. func1(req,res,callback);
  5. func2(req,res,callback);
  6. func3(req,res,callback);
 

输出内容:

  1. in func3
  2. in func2
  3. in func1

原因是因为nodejs是异步的,func2不会等func1执行完毕后再执行,而是立即执行(func3也是如此)。由于func3的运行时间最短而率先结束,func2次之,func1最后。但这明显不是我们想要的结果。怎么办?

解决办法一:callback

 
  1. //深层嵌套
  2. var req = null;
  3. var res = null;
  4.  
  5. func1(req,res,function(){
  6. func2(req,res,function(){
  7. func3(req,res,function(){
  8. process.exit(0);
  9. })
  10. });
  11. });
 

这种方法虽然能快速的解决,但暴露的问题也很明显,一是代码维护不方面,二是代码的深层嵌套看起来很不舒服。这种方法并不可取。

解决方法二:递归调用

 
  1. function executeFunc(funcs,count,sum,req,res){
  2. if(count == sum){
  3. return ;
  4. }
  5. else{
  6. funcs[count](req,req,function(){
  7. count++;
  8. executeFunc(funcs,count,sum,req,res);
  9. });
  10. }
  11. }
  12.  
  13. //同步调用
  14. var req = null;
  15. var res = null;
  16. var funcs = [func1,func2,func3];
  17. var len = funcs.length;
  18. executeFunc(funcs,0,len,req,res);
 

先将多个函数组成一个数组。再可以利用递归函数的特性,使程序按照一定的顺序执行。

解决方法三:调用类库

随着nodejs的发展,响应的类库也越来越多。Step和async 就是其中不错的。

1. Step的调用相对比较清爽:

 
  1. Step(
  2. function thefunc1(){
  3. func1(this);
  4. },
  5. function thefunc2(finishFlag){
  6. console.log(finishFlag);
  7. func2(this);
  8. },
  9. function thefunc3(finishFlag){
  10. console.log(finishFlag);
  11. }
  12. );
 

2.async 的 series方法,就本例而言,它的调用方法:

 
  1. var req = null;
  2. var res = null;
  3. var callback = function(){};
  4.  
  5. async.series(
  6. [
  7. function(callback){
  8. func1(req,res,callback);
  9. },
  10. function(callback){
  11. func2(req,res,callback);
  12. },
  13. function(callback){
  14. func3(req,res,callback);
  15. }
  16. ]
  17. );

如何让nodejs同步操作的更多相关文章

  1. Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

    声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...

  2. nodejs的第四天学习笔记

    一. ECMAScript6(es2015)es6语法 es6/es2015,在es5的基础上扩展了很多新的功能,我们要学习仅仅是es6中的部分常用新功能,这些功能在使用的时候一定要慎重,因为他们之中 ...

  3. [转]七天学会NodeJS

    转:http://nqdeng.github.io/7-days-nodejs/ NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS, ...

  4. NodeJs - 100

    Nodejs官方文档 https://nodejs.org/en/docs/ Nodejs官方网站 https://nodejs.org/en/ Nodejs的特征:  1.采用非阻塞性IO机制:—— ...

  5. 七天学会NodeJS (原生NodeJS 学习资料 来自淘宝技术团队)

    NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. ...

  6. (一)、NodeJS (转载)

    NodeJS基础                                                 ------ 转载自阿里巴巴 什么是NodeJS JS是脚本语言,脚本语言都需要一个解 ...

  7. NodeJS学习之文件操作

    NodeJS -- 文件操作 Buffer(数据块) JS语言自身只有字符串数据类型,没有二进制数据类型,因此NodeJS提供了一个与String对等的全局构造函数Buffer来提供对二进制数据的操作 ...

  8. NodeJS制作爬虫全过程

    这篇文章主要介绍了NodeJS制作爬虫的全过程,包括项目建立,目标网站分析.使用superagent获取源数据.使用cheerio解析.使用eventproxy来并发抓取每个主题的内容等方面,有需要的 ...

  9. Redis操作命令大全(NodeJS版)

    /*—————————————————————————————— * 本文案例基于以下运行环境: * 系统: CentOS 5.x * NodeJS版本: 0.9 以上 * Redis版本: 2.8 ...

随机推荐

  1. SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪个性能好?

    SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪个性能好? 今天遇到某人在我以前写的一篇文章里问到 如果统计信息没来得及更新的话,那岂不是统计出来的数据时错误的 ...

  2. myrocks 之数据字典

    data dictionary rocksdb作为mysql的一个新的存储引擎,在存储引擎层,会维护自已的元数据信息.在innodb存储引擎中,我们通过information_schema下的INNO ...

  3. array new 与 array deletedelete

    以前在看C++书和上C++课的时候可以看到 delete[] pointer; 的用法,而大多数对于这个用法没有具体的解释,多是看到: 有一个delete运算符的特殊语法,可以释放动态分配的数组内存: ...

  4. Mac中体验ASP.NET 5 beta2的K gen代码生成

    ASP.NET 5 beta2中增加了一个新特性(详见ASP.NET 5 Beta2 发布),可以通过K命令生成MVC的代码,比如:k gen controller -name HomeControl ...

  5. 作业2.3 Github注册过程

    过程: 1.百度搜索Github,并且进入官网.2.打开发现是全英文网页,网页右上角找到sgin up,单击进入. 3.输入用户名.邮箱.密码,完成后单击下面绿色图标. 4.之后发现进入选择价格界面, ...

  6. ECMAScript5的其它新特性

    之前两篇博客 ECMAScript5 Object的新属性方法,ECMAScript5 Array新增方法,分别介绍了ECMAScript5对Object和Array的拓展,这两个对象最常用,而且改动 ...

  7. Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力)

    系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...

  8. Git Day03,GitHub 1st

    1st, SSH key: Add a pic @ Sep 18 2016 20:26 To note the configuration process on Linux: 2nd,github网站 ...

  9. linux奇技淫巧 4

    压缩解压 tar 即可压缩也可以解压 c 压缩 如果没有z.j参数,则表示,只打包,不压缩. 就说, t 查看 z 以gzip方式压缩 相当于 gzip ?.. j 以bzip方式压缩 bzip2 ? ...

  10. MyBatis入门学习(三)

    在实际开发中,我们希望文件配置是分类配置存放,需要的时候引入即可.如果多文件的配置混合配置使用,那么对项目的后期维护将增加难度. 一.对于连接数据库的配置单独放在一个properties文件中 1.对 ...