Node.js异步编程

1.回调函数

Node.js是单进程,单线程的应用程序,而通过V8引擎提供的异步执行回调接口可以处理大量的并发请求,所以性能非常高.

Node.js几乎每个API都支持回调函数,用来维护并发.一边读取文件,一边执行其他的任务,读取完文件后,将文件的内容作为回调函数的参数进行返回,这样执行代码时就没有阻塞或等待I/O操作.

异步编程依托于回调函数来实现,但不意味着使用回调就异步化了.回调函数一般作为函数的最后一个参数出现,在回调函数内部,第一个参数为err用来接收代码中的错误,第二个参数接收真正返回结果的数据.

 function 函数名 (arg1,arg2,callback(err,result){}){}

实例:回调函数读取文本文件

input.txt内容:

main.js 

 因为是非阻塞,程序的执行不用按照顺序执行.

 1.1.阻塞

Node.js保留了JavaScript在浏览器中单线程的特点,单线程在程序执行时,程序按照连续的顺序依次执行.在Node.js标准库中一些I/O方法提供阻塞版本,名字通常以Sync结尾.

 当我们执行程序时,对话框未关闭时,控制台没有输出,关闭提示框,控制台输出.

1.2.非阻塞

阻塞是按顺序执行的,非阻塞是不需要按照顺序执行的.在Node.js标准库中,所以的I/O方法都提供异步模式.异步模式在执行是非阻塞的.就像上面的例子.

2.异步编程

目前广泛用于处理异步编程的方法有三种:事件发布/订阅模式,Promise/Deferred模式和流程控制库.

2.1 事件发布/订阅模式

在该事件模式下,一个事件对象用来发布事件,即为发布者.订阅发布者所发布的事件,即为订阅者.但发布者发布一个事件时,发布者会通知所有订阅了该事件的订阅者.

2.1.1 事件驱动

Node.js所有的异步I/O操作完成后,都会发送一个事件到事件队列.Node.js使用事件驱动模型,当Web服务器收到请求时,先将他关闭,再进行处理,再去服务下个Web请求.在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件后,会触发回调函数.流程图如下

2.1.2 EventEmitter类

Node.js有多个内置的事件,可以通过引入Events模块,并通过EventEmitter类来绑定和监听事件.

首先通过require加载Events模块,实例化一个对象

 EventEmitter提供了多个方法,如on(),emit().on()用于绑定事件函数,emit()用于一个事件触发.

常用方法和含义
方法功能
addListener(event,listener)指定事件添加一个监听器
on(event,listener)为指定事件注册一个监听器,接收一个字符串event和一个回调函数
emit(event,[arg1],[arg2],[...])按监听器的顺序执行每个监听器,如果事件有注册监听,则返回去true,否则返false

 代码分析

首先加载核心模块events,在实例化一个对象events.EventEmitter,在订阅事件.on()方法用来注册事件event的一个监听器,emit()方法提交事件执行监听器,此时输出A.addListener()为指定事件click的一个监听器,事件提交后,会调用该监听器,在控制台输出B

2.2 Promise/Deferred模式

JavaScript的异步编程需要回调函数的支持,但是当业务逻辑很复杂时,回调的多层嵌套会让复杂度飙升,可读性会大大降低,维护也会变得困难,这就是"回调地狱".

Promise是异步编程问题的一种解决方案.Promise可以将异步的操作以同步的操作流程表达出来,避免了层层嵌套,解决了"回调地狱"问题.在开发时须提供Promise(承诺)对象所需的业务处理函数,在Deferred(延迟对象)中将事件处理函数进行绑定,先执行异步调用,然后延迟传递处理对象.

Promise通常用于外部,代表一个异步操作,Promise对象有三种状态:Penging(进行中),Fulfilled(已完成),Rejected(失败)状态一旦被改变,不可以更改.

Deferred主要用于内部,以维护异步模型的状态.通过resolve()方法,改变自身状态为执行态.并触发then()方法的onfuilled回调函数.通过reject()方法改变自身状态为拒绝态,并触发then()方法的onrejected回调函数.

示例:

 2.3 流程控制库

在业务逻辑非常复杂时,异步嵌套逐渐增多,从而形成"异步地狱".对业务的逻辑和代码的维护造成困扰,处理异常也非常的繁琐.流程控制库主要用来控制多个异步回调时的顺序以及依赖.

async是node.js中流程控制模块,也可以在浏览器端使用.await用于等待一个异步方法执行完成.通过await处理async计算结果和错误.await只允许放在async()函数内部使用,它可以按顺序处理多个异步返回值.

原生方法读取多个文件:

 async和await方法

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值