NodeJs中的异步

原文引用https://www.dazhuanlan.com/2019/08/25/5d625d714f62a/

这篇文章主要讨论NodeJs中的异步问题。使用NodeJs编写进程也一年多了,在公司实习的时候,公司两个项目的后台都是我负责使用NodeJs和Sails框架编写的。工作模式主要是我在服务器端提供RESTful接口,网页端通过AJAX方式获取服务端的数据。在做的过程中,遇到了许多问题,感触最深的是异步编程的思维习惯还不是适应的很好。

异步背景

其实,异步很早都有了,例如在操作系统中就有异步的概念。后来随着Ajax技术的普及,前端的开发人员最了解异步这个概念。随着谷歌的Chrome浏览器的V8的推出,出现了以异步方式处理网络请求的Nginx服务器,时间证明,Nginx的并发性能比Apache,Tomcat等更出色。在V8推出后,Ryan Dahl就推出了NodeJs,第一个在语言平台完全支持NodeJs的技术。当然Java,PHP等也都支持异步方式的编程,但是那都是在Java语言的基础上通过多线程及线程间的通信上实现的。而NodeJs在语言的实现上就是以异步的思想为基础的。

异步的实现

要讲异步,就得了解阻塞IO与非阻塞IO。
阻塞IO我们很好理解,因为在平常的编程中,我们经常读写文档,例如在C语言中我们使用open函数打开一个比较大的文档,那么这个时候进程就会阻塞住,直到文档读取完毕,后续的操作才能继续。

非阻塞IO则是使用另一个线程去读取大文档,主线程的后续操作可以不用等待读取线程而继续运行。但是这个时候我们在主线程中就不知道读取线程何时操作完毕。所以我们就是用轮询的技术,每个一个时间间隔,就去查看读取线程是否操作完毕。在Linux中,这种轮询可以通过read, poll, epoll, kqueue的方式实现,但是轮询技术有个缺点,就是轮询的时候,主线程必须等待,使CPU空置起来了。

最理想的非阻塞IO则是主线程和读取线程基本互不干扰,只有当读取线程操作完毕后,才会通知主线程读取完毕。NodeJs通过libuv来实现异步,而libuv则会根据操作系统平台使用相应的实现方式。如在Linux中,通过线程池的方式实现,在Windows平台则通过调用IOPC实现,其实IOPC也是使用线程池的方式实现,只不过Windows在内核中实现了而已。

总的来说,NodeJs虽然讲是单线程,异步,事件驱动的,但是这里我主要想讲,NodeJs也是通过多线程的方式实现异步的。我们所讲的单线程只是指向NodeJs代码运行的主线程而已,异步的操作都是通过底层线程池完成的。

当然,NodeJs是异步实现,那么我们在编写应用进程的过程中,就尽量使用异步的方式 – callback,这样我们的应用进程才能具有异步的高性能,否则还不如使用同步的方式编写。

NodeJs的多进程(线程)方法

并不是说NodeJs是单线程的就不支持多进程化,我们仍然可以使用NodeJs的child_process来实现多进程操作,这就与Linux的fork, exec等一样了,当然,若你不想使用这么原始的方式实现多进程,那么你可以通过NodeJs的cluster模块简单实现。

参考资料

深入浅出NodeJs - 第三章

深入浅出NodeJs - 第九章

NodeJs child_process

NodeJs cluster

原文地址:https://www.cnblogs.com/petewell/p/11408889.html

时间: 2024-08-06 17:31:12

NodeJs中的异步的相关文章

NodeJS中的异步I/O、事件驱动

nodejs的主要特点是单线程.异步I/O.事件驱动.让我们先大概了解一下这些名词的意思. 单线程 单线程是任务按照顺序执行的,并且每次只执行一个任务,只有前面的任务执行完成以后,后面的任务才执行.在JS引擎中负责解释和执行JavaScript代码的线程只有一个,即主线程.但实际上还存在其他的线程.例如处理AJAX请求的线程.处理DOM事件的线程.定时器线程.读写文件的线程等.这些线程可能存在与JS引擎之内,也可能存在与JS引擎之外,这些线程为工作线程. 同步和异步 同步:执行任务时,后面的任务

nodejs 中的异步之殇

nodejs 中的异步之殇 终于再次回到 nodejs 异步中,以前我以为异步在我写的文章中,已经写完了,现在才发现,还是有很多的地方没有想清楚,下面来一一说明. 模块同步与连接异步 大家应该,经常使用 express 进行网站开发.express 本来的问题不是重点,你肯定要用到第三工具,redis, mysql 了之类的. redis 需要连接,而连接成功需要一个回调(他是一个异步).问题就在这里,这个问题是:倒底是 redis 先连接成功,还是 express 先启动成功? redis.o

如何优雅的处理Nodejs中的异步回调

前言 Nodejs最大的亮点就在于事件驱动, 非阻塞I/O 模型,这使得Nodejs具有很强的并发处理能力,非常适合编写网络应用.在Nodejs中大部分的I/O操作几乎都是异步的,也就是我们处理I/O的操作结果基本上都需要在回调函数中处理,比如下面的这个读取文件内容的函数: fs.readFile('/etc/passwd', function (err, data) { if (err) throw err; console.log(data); }); 那,我们读取两个文件,将这两个文件的内

NodeJS中常见异步接口定义(get、post、jsonp)

越来越多的人在使用nodeJS,作为一门服务端语言,我们不可避免的要写异步接口(ajax和jsonp).再次强调ajax和jsonp是两个概念,但是由于jquery的封装,使这两种异步接口的调用方式,看起来比较相近,但在底层差别还是比较大的(本文只写服务端的实现). 为了便于讲解我使用express框架来运行我的demo.并分别讲解如何获取参数,并返回结果.本文相当于一个基础篇,只写了一些常见的应用场景.漏掉一些复杂的场景,还望提醒. 一.Ajax——post请求 之所以先从post开始,是因为

nodejs中的异步回调机制

1.再次clear Timer定时器的作用 setTimeOut绝非是传统意义上的"sleep"功能,它做不到让主线程"熄火"指定时间,它是用来指定:某个回调在固定时间后插入执行栈!(实际执行时间略长于这个固定时间) 2.js或nodejs想"sleep"主线程怎么做? 可以自定义sleep休眠函数,原理就是 目标时间 >= 当前时间+sleepTime; 然后不断在while中tick时间.比较.直接看代码吧. function slee

Nodejs中使用异步流程控制Async

首先,我们都知道,Node基于事件驱动的异步I/O架构,所谓异步就是非阻塞,说白了就是一个事件执行了,我不必等待它执行完成后我才能执行下一个事件.所以在Node环境中的模块基本都是异步的,上一篇说到我在项目中改用了easymysql模块代替mysql模块,两个模块作查询的操作都是异步的,所以要实现嵌套查询往往会很麻烦,而且很大可能会报错.为此,为了实现查询同步,我引进了异步流程控制async模块,让js异步操作变成同步操作,这样一方面方便阅读理解,另一方面能够很好实现需求的目标,亲测有效~ up

nodejs中的异步流程序控制nsync

异步编程是指由于异步I/O等因素,无法同步获得执行结果时,在回调函数中进行下一步操作的代码编写风格,常见的如setTimeout函数.ajax请求等等http://cnodejs.org/topic/54acfbb5ce87bace2444cbfb并不是node中的,但是我们开发中经常使用使用npm init初始化项目安装cnpm install async --devhttps://www.npmjs.com/package/asynchttp://caolan.github.io/async

Node.js(十二)——NodeJs中的Promise

爬虫基于回调和事件的方式去实现,回调也是被诟病已久的问题尤其是callback这种,无论是阅读还是调试都很费劲,甚至我们连代码的堆栈都看不到,这是一种反人类的写法,Promise来拜托这种痛苦的方式 传统方式实现动画效果: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Promise animation</title> <style&g

在Nodejs中贯彻单元测试

在团队合作中,你写好了一个函数,供队友使用,跑去跟你的队友说,你传个A值进去,他就会返回B结果了.过了一会,你队友跑过来说,我传个A值却返回C结果,怎么回事?你丫的有没有测试过啊? 大家一起写个项目,难免会有我要写的函数里面依赖别人的函数,但是这个函数到底值不值得信赖?单元测试是衡量代码质量的一重要标准,纵观Github的受欢迎项目,都是有test文件夹,并且buliding-pass的.如果你也为社区贡献过module,想更多人使用的话,加上单元测试吧,让你的module值得别人信赖. 要在N