• 如何让nodejs同步操作


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

    需要执行的函数:

     
    var func1 = function(req,res,callback){
      setTimeout(function(){
        console.log('in func1');
        callback(req,res,1);  
      },13000);
    }
    var func2 = function(req,res,callback){ 
      setTimeout(function(){
        console.log('in func2');
        callback(req,res,2);
      },5000);
    }
    
    var func3 = function(req,res,callback){
      setTimeout(function(){
        console.log('in func3');
        callback(req,res,3);   
      },1000);
    }
     

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

     
    var req = null;
    var res = null;
    var callback = function(){};
    func1(req,res,callback);
    func2(req,res,callback);
    func3(req,res,callback);
     

    输出内容:

    in func3
    in func2
    in func1

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

    解决办法一:callback

     
    //深层嵌套
    var req = null;
    var res = null;
    
    func1(req,res,function(){
      func2(req,res,function(){
        func3(req,res,function(){
          process.exit(0);   
        })  
      });  
    });
     

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

     

    解决方法二:递归调用

     
    function executeFunc(funcs,count,sum,req,res){
      if(count == sum){
         return ; 
       }
       else{
        funcs[count](req,req,function(){
           count++;
           executeFunc(funcs,count,sum,req,res);
        });
       }  
    }
    
    //同步调用
    var req = null;
    var res = null;
    var funcs = [func1,func2,func3];
    var len = funcs.length;
    executeFunc(funcs,0,len,req,res);
     

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

     

    解决方法三:调用类库

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

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

     
    Step(
      function thefunc1(){
        func1(this);
      },
      function thefunc2(finishFlag){
        console.log(finishFlag);
        func2(this);
      },
      function thefunc3(finishFlag){
        console.log(finishFlag);
      }
    );
     

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

     
    var req = null;
    var res = null;
    var callback = function(){};
    
    async.series(
      [
        function(callback){
          func1(req,res,callback);
        },  
        function(callback){
          func2(req,res,callback);
        },
        function(callback){
          func3(req,res,callback);  
        } 
      ]
    );
  • 相关阅读:
    Yii数据库操作增删改查-[增加查询更新删除 AR模式]
    Yii2 关于时间格式的用法
    常用Linux命令
    数据库设计规范
    PHP代码规范
    git fetch 的简单用法:更新远程代码到本地仓库及冲突处理
    yii2 URL重写 nginx的配置
    Linux下免安装mysql
    在CentOS下搭建自己的Git服务器
    开源技术推荐之个人使用心得
  • 原文地址:https://www.cnblogs.com/vipstone/p/4749921.html
Copyright © 2020-2023  润新知