如何让nodejs同步操作

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

众所周知,异步是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);  
    } 
  ]
);
img_fa0be433d68c8212b2b0b3b1a564ccb1.png
如果本文对你有所帮助,请打赏——1元就足够感动我:)
支付宝打赏 微信打赏
联系邮箱:intdb@qq.com
我的GitHub: https://github.com/vipstone
关注公众号: img_9bde0f31ac4a0eca10b1bd7414b78faf.png


作者: 王磊
出处: http://vipstone.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,请标明出处。

相关文章
|
1月前
|
Go 计算机视觉
在Golang高并发环境中如何进行协程同步?
在此示例中,使用互斥锁来保护对共享计数器变量 c 的访问,确保并发的 HTTP 请求不会产生数据竞争。
45 3
|
6月前
|
Go
go的并发初体验、加锁、异步
go的并发初体验、加锁、异步
|
4月前
|
JavaScript
Electron——如何使用nodejs工作线程
Electron——如何使用nodejs工作线程
89 4
|
7月前
|
存储 Python
python使用gevent库来创建协程,并通过协程实现并发执行不同的任务
```markdown 这段Python代码利用`gevent`库实现并发执行协程。定义了两个打印函数`f1`和`f2`,分别输出"csdn"和"yyds"。代码首先创建列表`t_l`,并启动5个`f1`协程,将其加入列表并等待所有协程完成。随后,同样方式启动5个`f2`协程,存入`t1_l`列表并等待执行完毕。整体展示了`gevent`的协程并发操作。 ```
60 1
|
7月前
|
程序员 Linux 调度
用ucontext库创建简单的协程
用ucontext库创建简单的协程
135 0
|
JavaScript 前端开发
js单线程、同步、异步
什么是单线程?同步、异步的产生?
117 0
|
Python
Python 自带异步队列的大坑
Python 自带异步队列的大坑
223 0
|
JavaScript 前端开发 网络协议
Nodejs 必知的「事件循环」
JavaScript引擎本身不实现事件循环机制。浏览器中的事件循环由浏览器实现的,NodeJS中事件循环主要是由底层Libuv库实现的。 Libuv库是事件驱动的,其封装和统一了不同平台的API实现。NodeJS的跨平台和事件循环机制都是通过Libuv库实现的。
187 0
|
存储 开发工具 数据安全/隐私保护
乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。
众所周知,异步并发编程可以帮助程序更好地处理阻塞操作,比如网络 IO 操作或文件 IO 操作,避免因等待这些操作完成而导致程序卡住的情况。云存储文件传输场景正好包含网络 IO 操作和文件 IO 操作,比如业内相对著名的七牛云存储,官方sdk的默认阻塞传输模式虽然差强人意,但未免有些循规蹈矩,不够锐意创新。在全球同性交友网站Github上找了一圈,也没有找到异步版本,那么本次我们来自己动手将同步阻塞版本改造为异步非阻塞版本,并上传至Python官方库。
乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。
|
JavaScript Windows 内存技术
怎么使用 nvm 控制 nodejs 版本切换?
怎么使用 nvm 控制 nodejs 版本切换?
207 0
怎么使用 nvm 控制 nodejs 版本切换?