javascript如何实现单线程和异步 [英] how javascript single threaded and asynchronous

查看:48
本文介绍了javascript如何实现单线程和异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过下面的链接,对单线程javascript及其异步性质有所了解

I went through the link below and understood single threaded javascript and its asynchronous nature a little

https://www.sohamkamani.com/blog/2016/03/14/wrapping-your-head-around-async-programming/

但是我仍然有一个疑问,javascript是单线程的,并且它总是以顺序的方式向前移动,直到完成执行.

But I still have questions that javascript is single threaded and it always moves in forward direction in sequential manner until it finishes its execution.

每当我们调用具有回调的函数时,该回调将在函数收到响应后执行.在等待响应期间,将继续执行javascript代码.这样,在顺序发生执行的地方,如何在收到响应后立即恢复回调执行.就像线程正在向后移动以执行回调.

Whenever we made call to function which has a callback, that callback will be executed after function receives response. Execution of javascript code continues during the wait time for the response. In this way where execution happening in sequence how callback execution will be resumed once after response received. It's like thread is moving backwards for callback execution.

执行线程应该始终向前移动吗?

Thread of execution should always move in forward direction righy?.

请对此进行澄清.

推荐答案

JavaScript(该语言)不是单线程的,并且存在运行JavaScript的多线程环境(例如,通过其脚本支持的Java虚拟机)).语言本身在线程主题上基本没有任何意见.它确实定义了一个工作队列(面向浏览器的人称其为事件循环")和工作的运行至完成语义(请参见

JavaScript, the language, is not single-threaded, and there exist multi-threaded environments that run JavaScript (for instance, the Java virtual machine via its scripting support). The language itself is largely silent on the topic of threads. It does define a job queue (browser-oriented folks call it an "event loop") and run-to-completion semantics for jobs (see Jobs and Job Queues in the spec). More on that in a moment.

但是,大多数环境(包括浏览器)在每个全局环境中运行一个线程(或者有时在多个全局环境中运行一个线程),这就是为什么人们普遍认为"JavaScript是单线程"的原因.但是,即使在浏览器上,您也可以通过Web Worker拥有多个线程.他们并没有一个共同的全球环境,它带来了所有复杂的原因,但是他们可以交流.

However, most environments (including browsers) run one thread per global environment (or sometimes one thread for multiple global environments), which is why "JavaScript is single-threaded" is so commonly believed. But even on browsers, you can have multiple threads via web workers. They do not share a common global environment, with all the complications that causes, but they can communicate.

回到您的问题:

在单个线程上运行并具有异步回调完全没有冲突.JavaScript线程基于添加了作业的作业队列起作用.作业是运行至完成的代码单元.当该代码单元完成运行直至完成时,线程将从队列中拾取下一个作业并运行该作业.一个工作不能中断另一个工作(规范链接).尽管可以在工作线程上进行作业(通过

Running on a single thread and having asynchronous callbacks are not at all in conflict. A JavaScript thread works on the basis of a job queue that jobs get added to. A job is a unit of code that runs to completion. When that unit of code is done running to completion, the thread picks up the next job from the queue and runs that. One job cannot interrupt another job (spec link). Jobs running on the main UI thread cannot be suspended in the middle (mostly¹), though jobs on worker threads can be (via Atomics.wait). A thread with a suspended job is completely suspended, it does not pick up other jobs from its queue until it's resumed and completes the job that was suspend.

例如,考虑:

console.log("one");
setTimeout(function() {
  console.log("three");
}, 10);
console.log("two");

运行该命令时,您会看到

When you run that, you see


one
two
three

在控制台中

.这是发生了什么:

in the console. Here's what happened:

  1. 将用于执行主脚本的作业添加到作业队列中
  2. 浏览器的主要JavaScript线程完成了该任务
  3. 它运行了第一个 console.log setTimeout 和最后一个 console.log
  4. 工作终止
  5. JavaScript主线程闲置了一段时间
  6. 浏览器的计时器机制确定该 setTimeout 回调的时间到了,并将一个作业添加到作业队列中以运行它
  7. 主要的JavaScript线程接管了该工作,并运行了最后的 console.log
  1. A job for the main script execution was added to the job queue
  2. The main JavaScript thread for the browser picked up that job
  3. It ran the first console.log, setTimeout, and last console.log
  4. The job terminated
  5. The main JavaScript thread idled for a bit
  6. The browser's timer mechanism determined that it was time for that setTimeout callback and added a job to the job queue to run it
  7. The main JavaScript thread picked up that job and ran that final console.log

如果将主要的JavaScript线程捆绑在一起(例如, while(true); ),则作业只会堆积在队列中并且永远不会得到处理,因为该作业永远不会完成.

If the main JavaScript thread were tied up (for instance, while (true);), jobs would just pile up in the queue and never get processed, because that job never completes.

¹作业是运行到完成的代码单元." 作业不能在中间暂停..." 这里有两个警告:

  1. alert confirm prompt –那些90年代的同步用户互动 —在等待用户时暂停主UI线程上的作业.这是过时的行为(已被部分废止,并且至少已部分逐步淘汰).

  1. alert, confirm, and prompt — those 90's synchronous user interactions — suspend a job on the main UI thread while waiting on the user. This is antiquated behavior that's grandfathered in (and is being at least partially phased out).

自然地,主机进程—浏览器等.可以在作业运行时终止正在运行的整个环境.例如,当网页变为无响应"时,浏览器可以将其杀死.但这不只是工作,而是工作运行的整个环境.

Naturally, the host process — browser, etc. — can terminate the entire environment a job is running in while the job is running. For instance, when a web page becomes "unresponsive," the browser can kill it. But that's not just the job, it's the entire environment the job was running in.

这篇关于javascript如何实现单线程和异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆