一、为什么js是单线程?
所谓单线程,是指在js引擎中负责解释执行js代码的线程只有一个,不妨叫他主线程。
但是实际上还存在其他的线程。例如:处理ajax请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程等等。这些线程可能存在于js引擎之内,或之外。这里统称为工作线程
js的单线程与它的用途有关。作为浏览器脚本语言,js的主要作用就是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,js上有两个线程,一个线程在DOM某节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?所以为了避免这种复杂性,从一诞生,js就是单线程,将来也不会改变
二、一个例子引发问题
for(var i = 1;i<=3;i++){ setTimeout(function(){ alert(i); },100); }
js中会弹出三次4,而不是一眼望去的1,2,3。其原因就在于异步运行
三、异步任务
所有任务可以分为两种:同步任务和异步任务。同步任务指的是在主线程上排队执行的任务,异步任务指的是不进入主线程、而进入“任务队列”的任务。
一个异步过程通常是这样的:
主线程发起一个异步请求,相应的工作线程接受请求并告知主线程已收到(异步函数返回);主线程继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作后,通知主线程;主线程收到通知后,执行一定的动作(调用回调函数)
异步函数通常具有以下形式:
A(args...,callback)
从主线程角度看,一个异步过程包括两个要素:发起函数A和回调函数callback
它们都是在主线程上调用,其中注册函数用来发起异步过程,回调函数用来处理结果。当然不一定是这种格式比如:
var xhr = new XMLHttpRequest(); xhr.onreadystatechange = xxx;//回调函数 xhr.open('GET',url); xhr.send();//发起函数
四、消息队列和事件循环
异步过程中,工作线程在完成异步操作后需通知主线程。那么这个通知机制时怎样实现的呢?答案就是消息队列和事件循环。
一句话就是:
工作线程将消息放到消息队列中,主线程处理完同步任务后通过事件循环去消息队列上取消息并处理
消息队列:FIFO
事件循环:指主线程重复从消息队列中取消息、执行的过程
主线程只有将当前的消息执行完成后,才会去取下一个消息。这种机制就叫事件循环机制,取一个消息并执行的过程叫做一次循环。而所谓的事件举个例子
var button = document.getElement('#btn'); button.addEventListener('click', function(e) { console.log(); });
这里的addEventListener就是发起函数,当鼠标点击该button时工作线程任务完成,将回调函数加入消息队列并通知主线程
异步过程如下图:
五、例子解释
setTimeout的真正含义是:在指定的毫秒数后,将定时任务处理的函数添加到执行队列的队尾。
这段函数的过程大致是:在执行到setTimeout函数时,异步线程返回继续执行for循环,当主线程上代码走完时而且时间到了100毫秒时,会有三个回调函数进入到消息队列等待执行,这时i===4,事件循环的结果就是弹出三个4
相关推荐
【Tornado Asyntool:让TornadoWeb异步运行的利器】 Tornado Asyntool 是一个专门针对 TornadoWeb 框架设计的工具,它的主要目标是简化异步代码的编写和执行,使得开发者能更高效地利用 Tornado 的非阻塞I/O模型。...
尤其在异步运行状态下,同步电机的性能更是引起了广泛的关注。异步运行是指同步电机在失去同步转速后的一种过渡运行状态,这种状态在电力系统中可能会因为各种原因而出现,例如电网故障或电机启动时。同步电机的异步...
电子政务-发电机非全相及大滑差异步运行过压保护装置.zip
2. **仿真和模拟**: 在复杂的仿真模型中,不同的模拟过程可能并行进行,使用异步并行计算可以显著减少总运行时间。 3. **优化算法**: 在优化问题中,可能需要同时尝试多个解决方案,异步并行计算可以加速这一过程。...
在“Labview2015多线程异步调用工程”中,我们探讨的核心是利用多线程和异步调用来提高程序执行效率和并发能力。这个工程的目的是让主线程能持续快速地进行轮询,同时多个子线程可以并行处理耗时的任务,从而优化...
:game_die: 节点异步执行 异步运行 exec 命令并在需要时更改目录以运行命令的包。特征异步运行 shell 命令。 在特定目录中运行 shell 命令/命令。 在后台使用和 。 可用于构建基于 CLI 和 Node.js 的工具。安装 # ...
【标题】:“zap:专注于性能和资源效率的异步运行时” 在计算机科学领域,运行时(Runtime)是指一个程序在执行过程中所依赖的环境,它提供了基础的系统服务,如内存管理、线程调度等。zap是一个专为实现高性能和...
smol Rust的小型快速异步运行时。 该运行时使用异步组合器扩展了标准库,并且只有1500行代码。 Re smol一个用于Rust的小型且快速的异步运行时。 该运行时使用异步组合器扩展了标准库,并且只有1500行代码。 阅读文档...
**smol:Rust的小型快速异步运行时** 在编程世界中,异步编程已经成为高性能、高并发应用的关键技术。Rust作为一种系统级编程语言,以其强大的内存安全特性和高性能而闻名,而smol(读作"small")正是Rust社区为...
"awak: Rust的小型异步运行时"是一个专注于异步编程的项目,它为Rust开发者提供了一个轻量级的运行环境,以便在处理大量并发任务时,能够更高效地利用系统资源。 异步编程是一种编程范式,允许程序在等待I/O操作...
标题"异步运行工作流以提高性能"指出,本文关注的是如何利用异步操作来优化WF4的工作流执行效率。描述中提到通过实施不同的技术来实现简单的数学计算并比较执行时间,这表明文章可能探讨了多种异步策略及其性能差异...
调度器该库中的对象异步运行回调,从而允许在调用之间进行有用的暂停。 这可用于负载平衡,速率限制,延迟执行。 在下面的示例中,对象在构造函数之后立即接收任务。 但是实际上,对象可以在随机时间处理对run方法的...
JavaScript 对方法的最简单的异步运行支持。 这很容易 /* AsynCallJS 1.3.5 - JavaScript's Easiest Async-Run Support For Methods. * https://github.com/eladkarako/AsynCallJS/ * * Copyright (c) 2015 ...
斑马cURL 高性能的cURL PHP库允许异步异步运行多个请求 Zebra cURL是一个高性能的cURL PHP库,它不仅允许一次运行多个异步请求,而且可以立即处理完成的线程,而不必等待队列中的其他线程完成。 同样,每次完成一个...
RxJava2.0是Java开发中的一个强大的响应式编程库,尤其在处理异步操作时,它提供了一种声明式的编程方式,使开发者能够更优雅地处理事件和数据流。这个压缩包文件“TestRxJava20”很可能包含了示例代码,帮助新手...
Vim Plumber - 使用命名管道异步运行 ruby 测试Plumber 旨在通过使用单个键映射来根据 vim 中的当前文件运行最相关的测试,从而加快您的 TDD 周期。 它使用 unix 命名管道将命令发送到辅助会话。 这意味着在当前...
一个简单的工具,用于同步编写程序但使用 yield 异步运行它。 安装 $ npm install yield-async 要使用 yield-async,您必须为生成器运行 node 0.11.13或更高版本,并且必须使用--harmony标志运行 node(1)。 如果你...
它允许您为依赖项和服务本身注册异步运行状况检查,并提供暴露其状态的运行状况终结点。 什么是明智之举? 该项目以德语单词Gesundheit命名,意思是“健康”,发音为/ɡəˈzʊntˌhaɪ̯t/ 。 安装 使用go模块: ...
### Rust异步请求详解 ...通过结合 `Future`、`async/await` 语法和强大的异步运行时,Rust 能够有效地处理 I/O 密集型任务,同时保持高性能和内存安全性。理解这些核心概念对于高效开发现代 Rust 应用程序至关重要。
Java中的半同步半异步模式旨在解耦并发系统中的异步和同步处理,提高效率和性能。... - 半同步半异步设计模式用于解决应用程序的一部分同步运行,而另一部分异步运行,并且两个模块需要相互通信的情况。