我浏览了下面的链接,了解单线程javascript及其异步性质
https://www.sohamkamani.com/blog/2016/03/14/wrapping-your-head-around-async-programming/
但是我仍然有一些问题,即javascript是单线程的,并且它总是以顺序方式向前移动,直到它完成执行.
每当我们调用具有回调函数时,该函数将在函数接收到响应后执行.在响应的等待时间内继续执行javascript代码.通过这种方式,执行顺序执行后如何在收到响应后恢复执行回调执行.这就像线程向后移动以进行回调执行.
执行线程应始终向前移动righy?
请澄清一下.
T.J*_*der 22
JavaScript(语言)不是单线程的,并且存在运行JavaScript的多线程环境(例如,通过其脚本支持的Java虚拟机).语言本身在线程主题上基本保持沉默.它确实定义了一个作业队列(面向浏览器的人称之为"事件循环")和作业的运行完成语义(请参阅规范中的作业和作业队列).稍等一下.
但是,大多数环境(包括浏览器)在每个全局环境中运行一个线程(或者有时一个线程用于多个全局环境),这就是人们普遍认为"JavaScript是单线程的"的原因.但即使在浏览器上,您也可以通过Web worker获得多个线程.他们没有共同的全球环境,导致所有并发症,但他们可以沟通.
回到你的问题:
在单个线程上运行并具有异步回调根本不会发生冲突.JavaScript线程基于作业添加到的作业队列工作.作业是运行完成的代码单元.当该代码单元完成运行时,该线程从队列中获取下一个作业并运行该作业.一项工作不能中断另一项工作(规范链接).在主UI线程上运行的作业不能在中间暂停(主要是¹),尽管工作线程上的作业可以是(通过Atomics.wait).具有挂起作业的线程完全挂起,它不会从其队列中获取其他作业,直到它恢复并完成暂停的作业.
例如,考虑一下:
console.log("one");
setTimeout(function() {
console.log("three");
}, 10);
console.log("two");Run Code Online (Sandbox Code Playgroud)
当你运行它时,你会看到
one two three
在控制台中.这是发生的事情:
console.log,setTimeout和去年console.logsetTimeout回调并将作业添加到作业队列以运行它console.log如果主JavaScript线程被绑定(例如while (true);),则作业将堆积在队列中并且永远不会被处理,因为该作业永远不会完成.
¹ "作业是一个运行完成的代码单元." 并且"工作不能暂停在中间..."这里有两个警告:
alert,confirm和prompt - 那些90年代的同步用户交互 - 在等待用户时暂停主UI线程上的作业.这是过时的行为(并且至少部分被逐步淘汰).
当然,主机进程 - 浏览器等 - 可以在作业运行时终止作业运行的整个环境.例如,当网页变得"无响应"时,浏览器可以将其终止.但这不仅仅是工作,而是工作所在的整个环境.
只需添加到上面的 TJCrowder\xe2\x80\x99s 答案即可:
\n\n作业队列称为事件循环,它跟踪所有需要执行的回调。每当回调准备好执行时(例如:异步操作完成后),它就会添加到事件循环中。
\n\n正如 TJ Crowder 所解释的,您可以将事件循环想象为一个队列。每当循环中有要执行的回调时,循环就会控制主线程并执行该回调。当这种情况发生时,正常流程的执行将停止。这样 JavaScript 就可以被想象成一种单线程语言。
\n\n您可以在 Philip Roberts 的精彩演讲中了解有关事件循环及其工作原理的更多信息。
\n| 归档时间: |
|
| 查看次数: |
1995 次 |
| 最近记录: |