Node.js中的非阻塞或异步I / O是什么?


136

在服务器端Javascript引擎的上下文中,什么是非阻塞I / O或异步I / O?我认为这是相对于Java服务器端实现的优势。


3
考虑浏览器环境中的脚本标签以帮助理解此概念很有帮助。Zakas对此发表了一篇很棒的文章-前几节应该足以解释阻塞的概念:nczonline.net/blog/2010/08/10/what-is-a-non-blocking-script
netpoetica

Answers:


317

同步与异步

同步执行通常是指按顺序执行的代码。异步执行是指未按照代码中出现的顺序运行的执行。在以下示例中,同步操作导致警报按顺序触发。在异步操作中,虽然alert(2)似乎执行第二次,但不是。

同步:1,2,3

alert(1);
alert(2);
alert(3);

异步:1,3,2

alert(1);
setTimeout(() => alert(2), 0);
alert(3);

阻塞与非阻塞

阻塞是指阻塞进一步执行直到该操作完成的操作。非阻塞是指不阻塞执行的代码。在给定的示例中,localStorage是一个阻塞操作,因为它使执行停止进行读取。另一方面,fetch是非阻塞操作,因为它不会alert(3)因执行而停顿。

// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);

// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);

优点

非阻塞异步操作的一个优点是,您可以最大程度地利用单个CPU和内存。

同步阻塞示例

同步阻塞操作的一个示例是某些Web服务器(如Java或PHP中的Web服务器)如​​何处理IO或网络请求。如果您的代码从文件或数据库中读取,则代码“阻止”执行后的所有内容。在此期间,您的计算机为没有执行任何操作的线程保留内存和处理时间。

为了在该线程停止运行时满足其他请求,取决于您的软件。大多数服务器软件所做的就是生成更多线程来满足其他请求。这需要更多的内存消耗和更多的处理。

异步,非阻塞示例

异步,非阻塞服务器(如Node中制造的服务器)仅使用一个线程来服务所有请求。这意味着Node实例可以充分利用单个线程。创建者在设计时以I / O和网络操作为瓶颈。

当请求到达服务器时,将一次为它们提供服务。但是,例如,当所服务的代码需要查询数据库时,它会将回调发送到第二个队列,并且主线程将继续运行(它不等待)。现在,当数据库操作完成并返回时,相应的回调从第二个队列中退出,并在第三个队列中排队等待执行。当引擎有机会执行其他操作时(例如清空执行栈时),它将从第三个队列中选择一个回调并执行它。


5
我不确定我是否理解PHP中的Blocking下的第二段。您是在说:“虽然PHP通常会阻止IO,但这不是因为OS自动将IO操作线程化。”?或者,您是说这不是PHP中的问题,因为PHP会为每个请求自动创建一个新线程,因此一个被阻止的请求不会停止整个PHP环境?(我猜是后者..)
dcow

6
是后者。
约瑟夫

2
等等,如果是后者,那么非阻塞I / O PHP(例如reactPHP或其他东西)比阻塞I / O PHP有什么优势。仍然
令人

5
@CharlieParker是的。异步操作与您的代码并行运行。但是,当主代码不忙时,“返回”异步操作结果的回调将在主代码中排队等待执行。
约瑟夫

2
@CharlieParker 这是一篇有关异步机制内部的文章。
约瑟夫

7
var startTime = new Date().getTime();
var getEndTime = () => {
    var tempEndTime = new Date().getTime();
    var second = (tempEndTime - startTime)/1000
    return `took ${second} sec...to finish\n`
}

console.log('1: start App', getEndTime())
setTimeout(()=>{
    console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())

// console -> Process Order:  1 -> 3 -> 2

代码示例

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.