前言
Node使得异步编程首次出现在业务层面,它借助异步I/O模型和V8高性能引擎(事件循环机制),突破单线程的性能瓶颈,让JavaScript在后端达到了实用价值。由于这种异步编程的出现,对于node,也会出现一些难点。
难点1 异常处理
说到异常捕获,相信大家都会想到try/catch/final,但是对于异步编程这种方式并不适用。
伪代码如下:
try{
async(callback);
}catch(e){
}
假设async是一个异步方法,调用async方法后,就会产生一个事件,事件(callback)会被放入该有的队列中,到了下一次事件循环(Tick),会却从队列中取出,把回调的内容传递给异步函数。因为这种情况,对异步方法进行try/catch操作只能捕获当次事件循环内的异常,对callback执行回调时候抛出的异常是无能为力的。
由于这种异常捕获的难点,Node在处理异常上形成了一种约定,将异常作为回调函数第一个实参传回,如果为空值,则表明异步调用没有异常抛出。
异步方法调用例子
async(function(err,result){
//TOO
})
我们在代码编写过程中,自己编写的异步方法,也要遵循这样一些规则。
- 必须执行调用者传入的回调函数
- 正确传递回异常共调用者判断
异步方法代码例子如下
var async=function(callback){
process.nextTick=something;
if(error){
return callback(error);
}
callback(null,results);
});
难点2 阻塞代码
javascript编程没有sleep()这样的线程沉睡功能,要想实现延时操作只能使用setInterval()和setTimeout()这两个函数。但是node是异步的,这两个函数并不阻塞后续代码的持续执行。(遇到这种睡眠一定时间的需求的时候,统一规划业务逻辑之后,调用setTimeout()的效果会更好)
难点3 多线程编程
难点4 异步转同步
Node提供了绝大部分的异步API和少量的同步API,但是异步编程有的时候需要根据流程,将逻辑梳理成顺序的同步形式,这种情况我们可以使用promise,和await等。
二者详细的学习地址:
难点5 函数嵌套过深
多个回调函数的互相依赖嵌套