(无聊)node.js之回调函数

node.js之回调函数

发现可以全文修改。那我就趁这几天不忙,,把nodejs的笔记全部整理一下吧。。先立个flag在这里,虽然没人看,但是也是学习的动力。。。

1.1.1 异步操作

  • 首先先了解什么是异步。说道异步,就会联系出来的他 的孪生兄弟——同步(synchronous),“同步模式”就是上一段的模式,后一个人物等待前一个人物结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的,同步的。
  • 而异步模式则完全不同,每一个任务有一个或多个回调函数,(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的,是异步的。异步模式非常重要。在浏览器端,好事很长的操作都应该异步执行。避免浏览器失去响应,最好的例子回事ajax操作。
  • 举一个大家都熟悉的例子:
<body>
       <button id="Button">展示异步操作</button>
       <script>
         var Button=document.getElementById('Button');
         Button.function(){
             alert('展示异步操作--a');
         }
         alert('展示异步操作--b');
       </script>
     </body>
  • 但是我一直有疑惑在于,JavaScript不是单线程语言吗?那他是如何做到异步操作的?所以——但凡“ 即是单线程又是异步 ”的语言都有一个共同的特点:它们是 event-driven 的,所以 Javascript 异步的实现也与其事件机制关系密切。
  • 在浏览器端的JavaScript实现了两个很重要的api,他们分别是定时器和AJAX请求。

定时器:

我。。。哦对啊,当你用定时器的时候,总会出现异步的情况啊
所以说,定时器如setTimeout被执行时,由浏览器的定时器线程执行的定时级数,而并不是JavaScript执行线程赋值计数。定时器线程在定时时间触发延时事件并将延时事件推入JavaScript事件队列。当JavaScript主线程同步diamante执行完毕时,会去轮询该事件对垒,取出最开始事件的处理函数推入主线程中被执行

AJAX

AJAX请求和定时器类似,同样是委托浏览器线程代为执行好事任务,这里是皆有浏览器的HTTP请求线程发起对服务器的请求,在请求得到响应后出发请求完成事件,将回调函数推入事件按队列等待执行

当然,上面只是浏览器端,在NodeJs的异步实现和浏览器端有所不同,

在NodeJs中Libuv为Nodejs提供了跨平台,线程池,事件池,异步I/O等能力,是Nodejs如此强大的关键。Libuv为上层的Nodejs提供了统一的API调用,使其不考虑平台差距,隐藏了底层实现。
我。。。实在是不好理解了,复制粘贴算了
发起 I/O 调用

1 用户通过 Javascript 代码调用 NodeJS 核心模块,将参数和回调传入核心模块

2 NodeJS 核心模块将传入参数和回调封装为一个请求对象

3 将这个请求对象推入到I/O线程池中等待执行

4 Javascript 发起的异步调用结束,Javascript 线程继续执行后续操作

执行回调

1 异步任务完成之后,会将结果存放在请求对象的 result 属性上,并发出操作完成通知

2 每次事件循环时会检查 I/O 线程池中是否存在已经完成的 I/O 操作,如果有就将请求事件加入到I/O观察者队列当中(事件队列),之后当作事件处理

3 处理I/O观察者事件时,会将之前封装在请求对象中的回调函数取出,并将 result 参数传入执行,以完成 Javascript 回调的目的

我们知道 NodeJS 非常适合开发 IO 密集型应用,但并不适合开发 CPU(计算) 密集型应用。为什么会这样呢?因为 NodeJS 异步的天性,在处理并发 IO 的时候不会阻塞主线程,实际上这种异步是借助于多线程实现的,IO 任务完成之后排队等待主线程执行。因为 NodeJS 主线程执行同步代码的速度非常之快,所以完全可以 hold 得住大规模的并发请求。但这也有存在例外,如果 NodeJS 主线程在执行同步任务的时候遇到一些计算量非常大,或者执行循环太久,等非常耗时的操作的时候,就会导致后续的代码以及事件队列里已完成的 IO 任务迟迟得不到执行,严重拖垮 NodeJS 的性能。

JavaScript是单线程语言,异步函数是由nodejs V8提供的事件完成的。
Node.js使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

1.1.2 回调函数(主要内容来源于菜鸟教程)

Node.js异步编程的直接体现就是回调。异步编程依托于回调来实现,但不能说是用了回调后程序就异步化了。
回调函数在完成任务后就会被调用,Node使用了大量的回到函数,Node所有API都支持回调函数。
例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。
回调函数一般作为函数的最后一个参数出现:

function foo1(name, age, callback) { }
function foo2(value, callback1, callback2) { }

举一个应用了回调函数的例子 :

var fs=require("fs");
	fs.readFile('input.txt',function(err,data){
	if(err) return console.error(err);
});
console.log("程序执行结束!")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值