我读过
Node.js是单线程的,即它以单一的顺序或方向执行代码。在给定的时间,只执行一个任务/调用。异步和单线程:执行不等待当前请求完成并移动到下一个请求/调用。
我在两个单线程和异步之间感到困惑。如果一个任务是setTimeout,另一个任务是从API获取数据,另一个任务是算术操作,那么进程是如何处理的呢?那么,考虑到其单线程的操作顺序是什么呢?
发布于 2021-12-05 19:37:02
在本例中,“单线程”意味着它在一个线程中运行Javascript。这意味着它运行Javascript的一部分,直到它将控制权返回到系统,只有这样,它才能运行附加到其他事件的代码。您的Javascript中没有两段是同时执行的。
FYI,为了本讨论的目的,我们忽略了WorkerThreads,这是运行Javascript的多个线程的一种有目的的方式,但不涉及一般的异步体系结构。
异步操作都是由nodejs在本机代码(通常是C/C++代码)中实现的。它们是诸如计时器、网络操作、磁盘操作等.本机代码(主要在跨平台库libuv
中)在Javascript中有接口,允许您调用它们,如http.request()
或fs.read()
,但是这些函数的底层核心实现是在本机代码中。这些操作的本机代码可能实际上在其实现中使用OS线程,也可能不使用。但是,这些线程完全隐藏在Javascript代码中。
例如,nodejs中的网络操作不使用线程。它们在操作系统中使用本机异步API,允许在网络操作完成时通知它们,而无需阻塞、旋转和等待。其他异步操作(如文件操作)实际上使用一个本地OS线程池来“模拟”异步体系结构。
因此,当Javascript作为单线程运行时,可以同时处理多个异步操作。如果您查看以下代码:
const fsp = require('fs').promises;
Promise.all([fsp.readFile("filea.txt"), fsp.readFile("fileb.txt")]).then(results => {
console.log(results[0]);
console.log(results[1]);
}).catch(err => {
console.log(err);
});
这将并行读取两个文件,并告诉您来自两个文件的数据何时可用。虽然Javascript仍然以单线程的形式运行,但底层文件操作使用OS级别的线程,磁盘操作在单独的线程中运行。因此,只有实际的Javascript是单线程的,而不一定是底层的异步操作。
幸运的是,您通常可以完全避免多线程编程所带来的并发问题,因为您自己的Javascript中有两段从未在同一时刻运行。因此,您不需要互斥或其他并发设备来安全地写入变量。线程使用的细节是抽象在异步接口后面的。而且,nodejs处理这些异步接口的方式的事件驱动性质决定了,在处理下一个具有下一个异步结果的完成事件之前,Javascript的一部分将运行以完成。
https://stackoverflow.com/questions/70237742
复制相似问题