1.在讨论浏览器与JavaScript之前,我们先来简单了解一下进程与线程
进程(process):资源分配的最小单位

进程是应用程序的执行实例,是操作系统进行资源分配和调度的一个独立单位。

线程(thread):CPU调度的最小单位

线程是进程内部的一个执行单元,是被系统独立调度和分派的基本单位。系统创建好进程后,实际上就启动执行了该进程的主执行线程。

上面这样讲可能不是很容易理解,我们以工厂模式来比喻:

  • 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行着。
  • 单个CPU一次只能运行一个任务
  • 进程就好比工厂的车间,它代表CPU所能处理的单个任务
  • 一个车间里,可以有很多工人。他们协同完成一个任务
  • 线程就好比车间里的工人,一个进程可以包含多个线程
2.浏览器多线程与Javascript单线程(单线程与多线程)

首先浏览器是多线程的,所以浏览器一次能够处理多个事件,比如渲染页面,脚本执行,事件处理等。

JavaScript是单线程的(浏览器只给JS分配了一个线程)

JavaScript单线程

单线程的特点就是一次只能处理一件事情。后一个任务需要等待前一个任务执行完再执行。

JS在单线程中实现异步机制只要依靠浏览器的任务队列,任务队列分为同步任务队列与异步任务队列,异步任务又可以分为宏任务与微任务

在同步任务自上而下执行时,如果遇到一个异步任务,不会立即执行,而是把它放到异步任务队列中去排队,当同步任务执行完成后,才会到异步任务队列进行查找等待任务队列中的内容(同步任务队列完不成,不管异步任务是否达到时间,都不执行),等达到条件后执行,然后再接着去异步任务队列中 查找。这就是因为js是单线程的,一次只能处理一件事情

JavaScript为什么要设计成单线程

JavaScript之所以采用单线程,而不是多线程,跟它的历史有关。最开始的JavaScript功能并没有现在这么强大,作为浏览器脚本语言,它最初主要是用来处理页面的用户交互,以及DOM的操作。如果JavaScript是多线程的话,假设存在两个线程同时操作一个DOM,这时候浏览器就不知道应该处理哪个线程的操作结果了。

3.同步与异步任务

**同步: ** 在一个线程上同一时间只能做一件事情,当情事情做完才能进行下一个任务。

异步: 在主栈中执行一个任务,但是发现这个任务是一个异步的操作,会将它放到异步任务队列中。

异步任务又分为宏任务与微任务:

宏任务:定时器setTimeout,setInterval,事件绑定,回调函数,node中的fs模块

微任务:new Promise().then(回调) ,process.nextTick(),async await

4.执行栈与任务队列

1)执行栈:从名字可以看出,执行栈使用到的是数据结构中的栈结构, 它是一个存储函数调用的栈结构,遵循先进后出的原则。它主要负责跟踪所有要执行的代码。 每当一个函数执行完成时,就会从堆栈中弹出(pop)该执行完成函数;如果有代码需要进去执行的话,就进行 push 操作。

2)任务队列: 从名字中可以看出,任务队列使用到的是数据结构中的队列结构,它用来保存异步任务,遵循先进先出的原则。它主要负责将新的任务发送到队列中进行处理。

执行顺序:

JavaScript在执行代码时,会将同步的代码按照顺序排在执行栈中,然后依次执行里面的函数。当遇到异步任务时,就将其放入任务队列中,等待当前执行栈所有同步代码执行完成之后,就会从异步任务队列中取出已完成的异步任务的回调并将其放入执行栈中继续执行,如此循环往复,直到执行完所有任务

先执行同步任务,执行完接着执行微任务,最后执行宏任务。这个过程会不断重复

下面看几道经典面试题
console.log("script start");

async function async1() {
await async2();
console.log("async1 end");
} async function async2() {
console.log("async2 end");
} async1(); setTimeout(function () {
console.log("setTimeout");
}, 0); new Promise((resolve) => {
console.log("Promise");
resolve();
})
.then(function () {
console.log("promise1");
})
.then(function () {
console.log("promise2");
}); console.log("script end");
// script start => async2 end => Promise => script end => async1 end=> promise1 => promise2 => setTimeout

解析:

1.首先执行同步任务:打印script start,async2 end,Promise,script end

2.同步任务执行完,开始执行微任务:async1 end,promise1,promise2

3.最后执行宏任务:setTimeout

JavaScript有同步任务和异步任务,浏览器是怎么处理的?的更多相关文章

  1. 「JavaScript」同步、异步、回调执行顺序之经典闭包setTimeout分析

    聊聊同步.异步和回调 同步,异步,回调,我们傻傻分不清楚, 有一天,你找到公司刚来的程序员小T,跟他说:“我们要加个需求,你放下手里的事情优先支持,我会一直等你做完再离开”.小T微笑着答应了,眼角却滑 ...

  2. 0182 JavaScript执行机制:单线程,同步任务和异步任务,执行栈,消息队列,事件循环

    以下代码执行的结果是什么? [结果是1 2 3 ] console.log(1); setTimeout(function () { console.log(3); }, 1000); console ...

  3. JavaScript同步模式,异步模式及宏任务,微任务队列

    首先JavaScript是单线程的语言,也就是说JS执行环境中,负责执行代码的线程只有一个.一次只能执行一个任务,如果有多个任务的话, 就要排队,然后依次执行,优点就是更安全,更简单.缺点就是遇到耗时 ...

  4. 详细解读XMLHttpRequest(一)同步请求和异步请求

    本文主要参考:MDN XMLHttpRequest 让发送一个HTTP请求变得非常容易.你只需要简单的创建一个请求对象实例,打开一个URL,然后发送这个请求.当传输完毕后,结果的HTTP状态以及返回的 ...

  5. JavaScript 学习笔记之线程异步模型

    核心的javascript程序语言并没有包含任何的线程机制,客户端javascript程序也没有任何关于线程的定义,事件驱动模式下的javascript语言并不能实现同时执行,即不能同时执行两个及以上 ...

  6. 【转载】Javascript里面的线程和异步

    JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序. 参考这篇文章 http://www.ruanyifeng.com/blog/2012/1 ...

  7. 使用HTTP的同步方式还是异步方式?

    同步与异步 同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完 ...

  8. 同步请求和异步请求的区别,ajax异步请求如何理解

    同步请求和异步请求的区别 先解释一下同步和异步的概念 同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式. 异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的 ...

  9. 通知url必须为直接可访问的url,不能携带参数 异步接收微信支付结果通知的回调地址 不能携带参数。 回调地址后是否可以加自定义参数 同步回调地址 异步回调地址 return_url和notify_url的区别

    [微信支付]微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7 通知url必须为直接可访问的 ...

随机推荐

  1. 刷题-力扣-1011. 在 D 天内送达包裹的能力

    1011. 在 D 天内送达包裹的能力 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/capacity-to-ship-packag ...

  2. Elasticsearch集群搭建教程及生产环境配置

    Elasticsearch 是一个极其强大的搜索和分析引擎,其强大的部分在于能够对其进行扩展以获得更好的性能和稳定性. 本教程将提供有关如何设置 Elasticsearch 集群的一些信息,并将添加一 ...

  3. Tomcat集群Cluster实现原理

    1.Tomcat集群         Tomcat集群的问题之一是如何处理Session,Session是有状态的,请求到了Tomcat,后续流传是要根据上下文(Context)来进行的.我们可以改造 ...

  4. 10分钟学会Visual Studio将自己创建的类库打包到NuGet进行引用(net,net core,C#)

    前言 NuGet就是一个包(package)管理平台,确切的说是 .net平台的包管理工具,它提供了一系列客户端用于生成,上传和使用包(package),以及一个用于存储所有包的中心库. 对于一个现代 ...

  5. python tif转jpg

    在同级目录完成tif和jpg的批量转换 import os import cv2 import numpy as np from osgeo import gdal #数据格式转化 def norma ...

  6. abp element 显示分页

    App.vue添加组件 <template> <div id="app"> <dataTable></dataTable> < ...

  7. 本地Markdown文件上传到博客

    本地Markdown文件上传到博客 参考:https://www.cnblogs.com/ccylhw/p/13954153.html 1.Typora 最漂亮的写作APPhttps://www.ty ...

  8. Java实现发送邮件,图片,附件

    参照地址 1.JavaMail 介绍 JavaMail 是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如前面 ...

  9. Spring Boot 2.x 之 Logging

    [源起] 最近在看Apollo的源码,发现其all-in-one项目的脚本demo.sh在执行的时候,竟然没有向控制台输出Spring Boot的日志. 我们修改后构建的Fat Jar,在启动时却打印 ...

  10. CTFd+ubuntu service搭建等待更新

    CTFd是一款基于Apache2.0的协议的开源CTF平台,最新版本目前为1.20.该平台功能强大,基本上能够满足目前的CTF竞赛需求,同时,该平台提供了强大的插件功能,可以自己进行插件开发实现自己的 ...