本地javascript是单线程且同步的。只有少数几个对象可以异步运行并被添加到回调队列中,例如HTTP请求,计时器和事件。这些异步对象是实际javascript环境的结果,而不是javascript本身的结果。 setTimeout()似乎是异步代码示例的首选。该函数将移至Web API容器,然后移至回调队列。似乎没有一种方法可以用javascript编写异步代码,该方法不涉及使用移动到Web API容器的对象。我可以使用回调编写自己的自定义对象,但是最能做的是构造它以正确的顺序运行。您永远无法编写不依赖于这些对象的并行运行的javascript代码。
这是我对它如何工作的理解,如果我错了,请纠正我。
答案 0 :(得分:1)
setTimeout
和setInterval
只是触发示例异步行为的一种便捷方法。在所有实现中,它都是标准javascript库的一部分,而不仅仅是浏览器环境的一部分。
但是所有其他异步代码源都依赖于某些外部过程。发出HTTP请求时,您的javascript线程会告诉浏览器发出请求(什么标头,什么url等)。浏览器根据其自身编译的内部信息,对请求进行格式化,发送,等待响应,并最终将项目添加到javascript的事件循环中,以在下次事件循环运行时进行处理。文件系统访问和数据库查询是异步代码的另外两个常见示例,它们取决于外部进程(分别是操作系统和数据库)
JavaScript如何在单线程进程中处理异步代码完全取决于此event loop。伪代码中的此事件循环基本上是这样的:
while (queue.waitForMessage()) {
queue.processNextMessage();
}
setTimeout
告诉环境在将来的某个时候将某些东西弹出到该队列中。但是该队列的处理是单线程的。只能同时处理一个事件消息,但是可以将任何数量的事件消息添加到该队列。
您可以使用workers获得真正的并发性,但这基本上增加了一个新的javascript进程,该进程本身是单线程的,并且具有与主要javascript进程之间进行消息通信的方法。