node.js中实现同步操作的3种实现方法


Posted in Javascript onDecember 05, 2014

众所周知,异步是得天独厚的特点和优势,但同时在程序中同步的需求(比如控制程序的执行顺序为: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);  

    } 

  ]

);
Javascript 相关文章推荐
ajax的hide隐藏问题解决方法
Dec 11 Javascript
修改file按钮的默认样式实现代码
Apr 23 Javascript
一个简单的全屏图片上下打开显示网页效果示例
Jul 08 Javascript
JavaScript模拟实现继承的方法
Mar 30 Javascript
jQuery使用$.ajax进行异步刷新的方法(附demo下载)
Dec 04 Javascript
判断是否存在子节点的实现代码
May 18 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
Apr 25 Javascript
vue2.0结合Element实现select动态控制input禁用实例
May 12 Javascript
详解Vue.js搭建路由报错 router.map is not a function
Jun 27 Javascript
关于JS与jQuery中的文档加载问题
Aug 22 jQuery
vue过滤器实现日期格式化的案例分析
Jul 02 Javascript
VUE实现吸底按钮
Mar 04 Vue.js
node.js实现BigPipe详解
Dec 05 #Javascript
js实现点击添加一个input节点
Dec 05 #Javascript
Node.js实现的简易网页抓取功能示例
Dec 05 #Javascript
浅谈js的setInterval事件
Dec 05 #Javascript
浅谈javascript中createElement事件
Dec 05 #Javascript
javascript的push使用指南
Dec 05 #Javascript
javascript结合ajax读取txt文件内容
Dec 05 #Javascript
You might like
全国FM电台频率大全 - 7 吉林省
2020/03/11 无线电
PHP完整的日历类(CLASS)
2006/11/27 PHP
php自定义函数之递归删除文件及目录
2010/08/08 PHP
变量在 PHP7 内部的实现(二)
2015/12/21 PHP
prototype class详解
2006/09/07 Javascript
fixedBox固定div漂浮代码支持ie6以上大部分主流浏览器
2014/06/26 Javascript
jQuery实现切换页面过渡动画效果
2015/10/29 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
2016/01/05 Javascript
谈一谈JS消息机制和事件机制的理解
2016/04/14 Javascript
基于Vue实现微信小程序的图文编辑器
2018/07/25 Javascript
js使用ajax传值给后台,后台返回字符串处理方法
2018/08/08 Javascript
vue3.0中使用element的完整步骤
2021/03/04 Vue.js
Python随机生成数据后插入到PostgreSQL
2016/07/28 Python
浅谈numpy中linspace的用法 (等差数列创建函数)
2017/06/07 Python
如何使用VSCode愉快的写Python于调试配置步骤
2018/04/06 Python
python学习--使用QQ邮箱发送邮件代码实例
2019/04/16 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
2019/06/26 Python
Python学习笔记之迭代器和生成器用法实例详解
2019/08/08 Python
利用pyecharts读取csv并进行数据统计可视化的实现
2020/04/17 Python
Pandas读取csv时如何设置列名
2020/06/02 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
2020/06/09 Python
python爬虫用mongodb的理由
2020/07/28 Python
微软开源最强Python自动化神器Playwright(不用写一行代码)
2021/01/05 Python
全球知名旅游社区巴西站点:TripAdvisor巴西
2016/07/21 全球购物
美国最大的网络男装服装品牌:Bonobos
2017/05/25 全球购物
韩国最大的购物网站:Gmarket
2019/06/20 全球购物
会展策划与管理专业大学生职业生涯规划
2014/02/07 职场文书
幼儿园区域活动总结
2014/05/08 职场文书
公司授权委托书格式范文
2014/10/02 职场文书
2014年最新离婚协议书范本
2014/10/11 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
2014年行风建设工作总结
2014/12/01 职场文书
安全生产协议书
2016/03/22 职场文书
如何避免mysql启动时错误及sock文件作用分析
2022/01/22 MySQL
使用Docker容器部署rocketmq单机的全过程
2022/04/03 Servers
java版 联机五子棋游戏
2022/05/04 Java/Android