读书笔记《七天学会NodeJS》(4) - 异步编程
Nodejs基于事件机制以及回调函数实现异步编程 回调与异步: 回调不等于异步,回调只是一个函数作为另一个函数的参数而已。一般实现异步的方式由setTimeout或SetInterval + 回调函数来实现。 此外很多API默认均是采用异步调用的方式实现。 代码设计模式: 1. 函数的返回值可以作为其他函数的参数,此外函数也可以作为其他函数的参数以实现回调函数嵌套,不过回调函数嵌套的层次太深会比较复杂。 2. 遍历数组的方式:串行同步遍历(直接依次遍历),串行异步遍历(异步回调时执行下一次递归函数来遍历),并行异步遍历(并行异步回调,并在回调函数中统计、判断是否遍历完成)。 3. 异常处理try{}catch(err){},只能用于同步执行的的代码,若在异步代码中抛出了异常,此时若没有在抛出异常的第一位置没有被捕获到,则直接以全局异常抛出导致程序退出; 此时可在异步回调函数内部即抛出异常的第一位置使用try{}catch(err){}来捕获。几乎NodeJs的所有异步API均按照此方式实现的,故而可与NodeJS的风格保持一致。一般此时回调函数的 第一个参数err包含是否出现了回调抛出了异常的状态值,可通过此值来判断。事实上,如果为同步执行的代码的情况下,只需要在入口点就可以捕获所有的异常。 如果我们编写的代码嵌套了很多层次的回调函数,则可能需要在每个嵌套的回调函数内try{}catch(err){}则可能导致代码异常复杂和难看。 此时对于这种情况,可采用domain域内置模块来简化异步代码的异常处理。 domain域: 域即一种运行环境。 1. 通过process全局对象来监听uncaughtException异常事件,可处理异常代码中没有捕获到的异常。 2. 通过domain域方式:即在异步代码执行前,通过domain.create创建子域对象并通过其run函数执行异步代码,此时该子域对象监听error事件,即可捕获到异步代码内部(含嵌套异步)异常。 无论哪种方式,基本上建议出现了类似的异常,若是不确定时建议重启程序,以避免某些可能的内存泄漏(底层因大量使用C/C++实现的)或其他错误导致程序异常。