nodejs中异步编程的原理是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
同步异步和阻塞非阻塞
在讨论nodejs的异步编程之前,让我们来讨论一个比较容易混淆的概念,那就是同步,异步,阻塞和非阻塞。
所谓阻塞和非阻塞是指进程或者线程在进行操作或者数据读写的时候,是否需要等待,在等待的过程中能否进行其他的操作。
如果需要等待,并且等待过程中线程或进程无法进行其他操作,只能傻傻的等待,那么我们就说这个操作是阻塞的。
反之,如果进程或者线程在进行操作或者数据读写的过程中,还可以进行其他的操作,那么我们就说这个操作是非阻塞的。
同步和异步,是指访问数据的方式,同步是指需要主动读取数据,这个读取过程可能是阻塞或者是非阻塞的。而异步是指并不需要主动去读取数据,是被动的通知。
很明显,javascript中的回调是一个被动的通知,我们可以称之为异步调用。
javascript中的回调
javascript中的回调是异步编程的一个非常典型的例子:
. getelementbyid(& # 39;按钮# 39;).addEventListener(& # 39;点击# 39;,,(),=祝辞,{ ,console.log (& # 39; button 点击! & # 39;); })
上面的代码中,我们为按钮添加了一个点击事件监听器,如果监听到了点击事件,则会出发回调函数、输出相应的信息。
回调函数就是一个普通的函数,只不过它被作为参数传递给了addEventListener,并且只有事件触发的时候才会被调用。
上篇文章我们讲到的setTimeout和setInterval实际上都是异步的回调函数。
回调函数的错误处理
在nodejs中怎么处理回调的错误信息呢? nodejs采用了一个非常巧妙的办法,在nodejs中,任何回调函数中的第一个参数为错误对象,我们可以通过判断这个错误对象的存在与否,来进行相应的错误处理。
fs.readFile(& # 39;/文件. json # 39;,,(呃,,数据),=祝辞,{ ,if (err !==, null), { ,//处理错误 ,console.log (err) ,返回 ,} ,//没有错误,则处理数据。 ,console.log(数据) })
回调地狱
javascript的回调虽然非常的优秀,它有效的解决了同步处理的问题。但是遗憾的是,如果我们需要依赖回调函数的返回值来进行下一步的操作的时候,就会陷入这个回调地狱。
叫回调地狱有点夸张了,但是也是从一方面反映了回调函数所存在的问题。
fs.readFile (& # 39;/a.json& # 39;,,(呃,,数据),=祝辞,{ ,if (err !==, null), { ,fs.readFile (& # 39;/b.json& # 39;,(呃,数据),=在{//才能callback inside 回调 ,}) ,} })
怎么解决呢?
别怕ES6引入了承诺,ES2017引入了异步/等待都可以解决这个问题。
ES6中承诺的
<强>什么是承诺强>
承诺是异步编程的一种解决方案,比传统的解决方案”回调函数和事件”更合理和更强的大。
所谓的承诺,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
从语法上说,承诺是一个对象,从它可以获取异步操作的消息。
承诺的特点
承诺有两个特点:
1,对象的状态不受外界影响。
承诺对象代表一个异步操作,有三种状态:待定(进行中),解决(已完成,又称实现)和拒绝(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2,一旦状态改变,就不会再变,任何时候都可以得到这个结果。
承诺对象的状态改变,只有两种可能:从等待变为解决和从等待变为拒绝。
这与事件(事件)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
承诺的优点
- <李>
承诺将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
李> <李>承诺对象提供统一的接口,使得控制异步操作更加容易。
李>承诺的缺点
- <李>
无法取消承诺,一旦新建它就会立即执行,无法中途取消。
李> <李>如果不设置回调函数,保证内部抛出的错误,不会反应到外部。
李> <李>当处于等待状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。