JavaScript是单线程、非阻塞、异步、并发的语言。
这使我感到困惑。如果JavaScript是单线程的,它怎么可能是并发的,它怎么可能是异步的,因为你需要跟踪你的异步代码正在做什么,并且没有另一个线程,这是不可能同时跟踪2个或以上的代码的。
啊..这里有一点需要说明:
JavaScript是单线程的,但它有很多空闲时间。
当它在等待网络加载、等待磁盘读取或等待操作系统返回数据时,它可以运行其他代码。
setTimeout(function() {
// Do something later.
}, 1000);
/// Sample code
document.addEventListener("click", function() { /* Handle click */ });
window.addEventListener("load", function() { /* handle load */ });
document.addEventListener("click", function() {
while(true);
});
如果您了解Webassembly,则目前已有一个提议,通过本地编译模块实现线程。
pthreads风格,请阅读此git问题跟踪器链接(1073)。
续上@Jeremy J Starcher的回答。
Javascript一直是单线程运行时,使用异步、非阻塞和事件驱动的执行模型。
要了解更多有关JS中事件循环执行的信息,我强烈推荐您观看这个Youtube视频。Philip Roberts的解释非常好。
在过去,开发人员会费尽周折地使用以下方法来实现类似于线程模型:
Worker()
API创建,但使用 DedicatedWorkerGlobalScope
。2. Service Worker(SIC - Mozilla)
服务工作者本质上是充当代理服务器的角色,位于Web应用程序、浏览器和网络之间(如果可用)。它们旨在(除其他功能外)实现有效的离线体验,拦截网络请求并根据网络是否可用以及更新的资源是否驻留在服务器上采取适当的措施。它们还将允许访问推送通知和后台同步API。
一个例子是在PWA-渐进式Web应用程序中使用,用于下载脚本、懒加载资产等目的。
JavaScript可能是“单线程”的(我不确定这是否真的是事实),但您可以使用/创建WebWorkers在主线程之外运行JavaScript。
因此,您可以同时并行运行两个代码片段。
当我们真正想表达的是我们的程序是这样还是那样时,我认为说一个语言是这样或那样是错误的。
例如:NodeJS是单线程的,并且可以异步运行代码,因为它使用事件驱动的行为。(某些事情出现并触发事件... Node处理它,如果它是像在线请求这样的东西,它会做其他事情而不是等待回应...当响应到达时,它会触发事件,Node捕获它并执行需要执行的操作)。
所以JavaScript是...
单线程的吗? 不是,因为您可以使用WebWorkers作为第二个线程
非阻塞的吗? 您可以编写阻塞主线程的代码。只需构建一个执行一亿次的for循环或不使用回调即可。
异步的吗? 不是,除非您使用回调。
并发的吗? 是的,如果您使用WebWorkers、回调或承诺(它们实际上是回调)