1.从一个简单的案例开始fs.readdir(path.join(__dirname,'./index.js'),(err,files)=>{files.foreach((filename,index)=>{fs.readFile((filename,'utf-8',(err,file)=>{...}))})})nodejs的特点是单线程,异步,非阻塞,if代码逻辑涉及如果有多个回调,会出现很烂的代码,不利于后期维护。2、nodejs为什么要设计成异步编程?异步编程流行ajax,所以对异步编程最熟悉的就是前端工程师了。但是在其他编程语言中,异步是很少见的。PHP是同步执行,自始至终都是阻塞的,这使得它在复杂的网络应用中无法表现出更好的并发性。当然我们不是在批评PHP,毕竟PHP是世界上最好的语言。PHP代码被设计成同步,帮助程序员顺序编写业务逻辑,这一点不容忽视。js是异步的。浏览器在同一个进程中执行js和UI渲染。如果js使用同步编程,会极大的影响用户体验。为什么js不是多线程的?首先,创建线程和执行线程上下文切换的开销比较大,其次,多线程编程经常面临锁和状态同步等问题。js的单线程编程方式更符合人们按顺序思考的方式,是主流的编程方式。但是单线程无法充分利用硬件资源。Node使用单线程避免多线程和状态同步等问题,使用异步I/O让单线程远离阻塞,更好的利用CPU。Node提供了类似于前端WebWorkers的子进程来高效地利用CPU。基于节点事件循环的执行方式使得回调函数非常普遍。对于一般的非异步回调函数,函数是我们自己调用的。三、异步编程的难点1、异常处理Node通常会将异常作为回调函数的第一个实参返回。如果第一个参数为null,则表示异步调用没有抛出异常。2、回调函数嵌套太深。一开始的案例是多个回调的嵌套,导致代码非常难懂,现在可以通过Promise、Generators、asyncfunctions来解决。其他还有多线程编程,异步转同步等。四、异步编程解决方案1、Promise/Deferred模式Promise/Deferred模式在一定程度上缓解了嵌套回调的问题。Promise只会处于未完成、完成和失败状态中的一种,永远不会完成。转化为完成状态或失败状态,不可逆转。并且完成状态和失败状态不能相互转化。Promise对象有一个then方法,接受完成状态和失败状态的调用,只接受函数对象,其他对象将被忽略。then方法继续返回Promise对象实现链式调用。functionasyncFunction(){returnnewPromise(function(resolve,reject){setTimeout(function(){resolve('AsyncHelloworld');},16);});}asyncFunction().then(function(value){console.log(value);//=>'AsyncHelloworld'}).catch(function(error){console.log(error);});//基本用法更新
