NodeJS实现同步的方法
NodeJS被打上了单线程、非阻塞、事件驱动…..等标签。 在单线程的情况下,是无法开启子线程的。经过了很久的研究,发现并没有thread函数!!!但是有时候,我们确实需要“多线程”处理事务。nodeJS有两个很基础的api:setTimeout和setInterval。这两个函数都能实现“异步”。 nodeJS的异步实现:nodeJS有一个任务队列,在使用setInterval函数的时候,会每隔特定的时间向该任务队列增加任务,从而实现“多任务”处理。但是,“特定的时间”不代表是具体的时间,也有可能是会大于我们设定的时间,也有可能小于。 我们跑跑下面代码块
setInterval(function() {
console.log(new Date().getTime());
}, 1000);
输出的结果如下:
1490531390640
1490531391654
1490531392660
1490531393665
1490531394670
1490531395670
1490531396672
1490531397675
......
我们可以看到,所有的时间间隔都是不一样的。时间的偏移不仅包含了间隔的1s,还包含了console.log()的耗时,以及new Date()的耗时。在大量的数据统计下,时间间隔近似于1s。
问题来了,setInterval是能实现多任务的效果,但是怎样才能实现任务之间的同步操作呢?这里实现的方法是通过回调函数实现的。
function a(callback) {
// 模拟任务a耗时
setTimeout(function() {
console.log("task a end!");
// 回调任务b
callback();
}, 3000);
};
function b() {
setTimeout(function() {
console.log("task b end!");
}, 5000);
}
a(b);
这里举了一个很简单的例子,就是将b方法的实现赋值给a方法的callback函数从而实现函数回调,但是会有个问题。假设a方法依赖于b方法,b方法依赖于c方法,c方法依赖于d方法…..也就意味着每个方法的实现都需要持有上一个方法的实例,从而实现回调。
function a(b, c, d) {
console.log("hello a");
b(c, d);
};
function b(c, d) {
console.log("hello b");
c(d);
};
function c(d) {
console.log("hello c");
d()
};
function d() {
console.log("hello d");
};
a(b, c, d);
输出结果
hello a
hello b
hello c
hello d
如果回调函数写的多了,会造成代码特别特别恶心。
如果有类似于sync的函数能让任务顺序执行就更好了。终于找到了async这个库 $ npm instanll async
async = require("async");
a = function (callback) {
// 延迟5s模拟耗时操作
setTimeout(function () {
console.log("hello world a");
// 回调给下一个函数
callback(null, "function a");
}, 5000);
};
b = function (callback) {
// 延迟1s模拟耗时操作
setTimeout(function () {
console.log("hello world b");
// 回调给下一个函数
callback(null, "function b");
}, 1000);
};
c = function (callback) {
console.log("hello world c");
// 回调给下一个函数
callback(null, "function c");
};
// 根据b, a, c这样的顺序执行
async.series([b, a, c], function (error, result) {
console.log(result);
});
注释基本能够很好的理解了,我们看看输出
hello world b
hello world a
hello world c
[ 'function b', 'function a', 'function c' ]
上面的基本async模块的实现的如果了解更多关于async模块的使用,可以点击:查看详情
其实nodeJS基本api也提供了异步实现同步的方式。基于Promise+then的实现
sleep = function (time) {
return new Promise(function () {
setTimeout(function () {
console.log("end!");
}, time);
});
};
console.log(sleep(3000));
输出结果为:
Promise { <pending> }
end!
可以看出来,这里返回了Promise对象,直接输出Promise对象的时候,会输出该对象的状态,只有三种:PENDING、FULFILLED、REJECTED。字面意思很好理解。也就是说Promise有可能能实现我们异步任务同步执行的功能。我们先用Promise+then结合起来实现异步任务同步操作。
sleep = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("start!");
resolve();
}, 1000);
})
.then(function () {
setTimeout(function () {
console.log("end!");
}, 2000);
})
.then(function () {
console.log("end!!");
})
};
console.log(sleep(1000));
输出结果:
Promise { <pending> }
start!
end!!
end!
在new Promise任务执行完后,调用了resolve才会执行所有的then函数,并且这些then函数是异步执行的。由输出结果可以知道。(如果所有then是顺序执行的应该是end! -> end!!)。但是上述也做到了两个异步任务之间顺序执行了。
不过,还有更加优雅的方式:使用async+await。
display = function(time, string) {
return new Promise(function (resovle, reject) {
setTimeout(function () {
console.log(string);
resovle();
}, time)
});
};
// 执行顺序:b a c
fn = async function () {
// 会造成阻塞
await display(5000, "b");
await display(3000, "a");
await display(5000, "c");
}();
输出结果:
b
a
c
由于这里时间输出比较尴尬,只能通过我们来感知,本人通过个人“感知”知道了在display b过度到display a的时候大概用了3s,再过度到display c的时候大概用了5s
NodeJS实现同步的方法的更多相关文章
- 使用UEditor 的时候,ajax注意使用同步的方法
使用UEditor 的时候,ajax注意使用同步的方法去读取后台数据,然后填写到前端的文本域当中.
- JAVA中线程同步的方法(7种)汇总
同步的方法: 一.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就 ...
- iOS网络编程同步GET方法请求编程
iOS SDK为HTTP请求提供了同步和异步请求两种不同的API,而且可以使用GET或POST等请求方法.我们先了解其中最为简单的同步GET方法请求. 首先实现查询业务,查询业务请求可以在主视图控制器 ...
- Docker Mongo数据库主主同步配置方法
一.背景 不多说,请看第一篇<Docker Mongo数据库主从同步配置方法> 二.具体操作方法 1.创建目录,如创建~/test/mongo_sr1和-/test/mongo_sr2两个 ...
- Docker Mysql数据库双主同步配置方法
一.背景 可先查看第一篇<Docker Mysql数据库主从同步配置方法>介绍 二.具体操作 1.创建目录(~/test/mysql_test1): --mysql --mone --da ...
- Java中线程同步的方法
同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注 ...
- java实现同步的方法
为何要实现同步 java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前 ...
- Java多线程系列三——实现线程同步的方法
两种实现线程同步的方法 方法 特性 synchronized 不需要显式地加解锁,易实现 ReentrantLock 需要显式地加解锁,灵活性更好,性能更优秀,结合Condition可实现多种条件锁 ...
- 多线程、同步实现方法及Error和Exception的区别与联系
多线程.同步实现方法? 实现线程有两种方法: 继承Thread类 实现Runnable接口 实现同步也有两种方法 一种是用同步方法:同步方法就是在方法返回类型后面加上synchronized, 比如: ...
随机推荐
- center os 7 安装 elasticSeartch
Centos7下安装配置elasticsearch 6.3.1 1)下载 Elasticsearch 6.3.1 地址:https://artifacts.elastic.co/downloads ...
- Linux -- 目录基本操作(1)
cd 切换目录 1.切换到指定目录下 #cd 相对/绝对目录 [root@localhost ~]# cd /home/tom/demo [root@localhost demo]# 2.切换到某个用 ...
- 常用 超全局数组$_server
$_SERVER 是一个包含了诸如头信息(header).路径(path).以及脚本位置(script locations)等等信息的数组.这个数组中的项目由 Web 服务器创建.不能保证每个服务器都 ...
- -L -Wl,-rpath-link -Wl,-rpath区别精讲
目录 前言 源码准备 源码内容 尝试编译,保证源码没有问题 编译 首先编译world.c 编译并链接hello.c 调试编译test.c 结论 转载请注明出处,谢谢 https://www.cnblo ...
- [译]C语言实现一个简易的Hash table(6)
上一章中,我们实现了Hash表中的插入.搜索和删除接口,我们在初始化hash表时固定了大小为53,为了方便扩展,本章将介绍如何修改hash表的大小. 设置Hash表大小 现在,我们的hash表是固定大 ...
- day11迭代器 and 闭包
函数名的使⽤以及第一类对象 函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量. 函数名就是变量名, 函数名存储的是函数的内存地址 函数名可以赋值给其他变量 函数名可以当做容器类 ...
- python教程(四)·序列
距离上次的小项目已经休息了很长一段时间,是时候来继续本系列教程了.这一节开始我们将深入python中的数据结构. 序列的概念 在python中,最基本的数据结构是序列,序列包含一个或多个元素,每个元素 ...
- 收藏Linux命令
http://www.cnblogs.com/laov/p/3541414.html#zhiling 1.压缩文件夹 http://www.cnblogs.com/eoiioe/archive/200 ...
- pwd命令的实现
pwd 命令描述 Linux中用 pwd 命令来查看"当前工作目录"的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd ...
- 20155334 实验二 Java面向对象程序设计
实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验要求 完成实验.撰写 ...