当前位置: 首页 > news >正文

Js的执行机制(异步)

Js的执行机制

JavaScript语言的一大特点就是单线程,同一个时间只能做一件事,这是js的诞生使命所致,比如对dom元素的添加和删除不能同时进行,应该先进行添加,之后再删除。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完
全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

单线程会带来相应的缺点,如果有一个任务时间过长,那么后续的任务全都得等待,如果有一个定时器三秒之后执行某函数,那么这三秒,下面的代码就没法运行了,所以要克服单线程的弊端,可以采取cpu调度的那种思想,虽然我只有一个cpu,但是可以在不同的时间内,轮番的执行各个任务,这就诞生了js的异步。

同步和异步

  • 同步:前一个任务结束后再执行后一个任务,比如我必须烧完了水以后再把菜切了。
  • 异步:在做这件事的同时,你还可以去处理其他事情,比如我先烧着水,把菜切了再去使用烧好的水。
  • 同步任务:同步任务都在主线程上执行,形成一个 执行栈
  • 异步任务:JS中的异步是通过回调函数实现的

回调函数

Js语言对异步编程的实现就是回调函数,所谓回调函数,就是把任务的第二段单独写在一个函数里,等重新执行这个任务时便直接调用这个函数,回调函数的英文名为callback,意为重新调用,比如一个3秒的定时器,先执行定时器,然后执行其他任务,3秒后再执行定时器中的回调函数。

异步任务有以下三种类型
普通事件,如click,resize等
资源加载,如load,error等
定时器,包括setInterval,setTimeout等
异步任务相关回调函数添加到任务队列中

Js代码的执行顺序:

  1. 先执行执行栈中的同步任务
  2. 异步任务(回调函数)放入任务队列中
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行

用一段代码来解释Js的执行机制:


console.log(1);
setTimeout(function() {
    console.log(3);
},1000);
console.log(2);

//执行的结果和顺序为 1、2、3
console.log(1);
setTimeout(function() {
    console.log(3);
},0);
console.log(2);

// 执行的结果和顺序为 1、2、3

程序从上到下依次执行,同步代码耗时比较短,放在主线程执行栈中,异步代码(回调函数)执行时间比较长,放在任务队列中,把栈中所有同步任务执行完了以后,再依次执行队列中的异步任务。
在这里插入图片描述
多个异步任务的情况
比如下面这段代码,有两个回调函数,一个是单击事件的,还有一个定时器的:

// 3. 第三个问题
console.log(1);
document.onclick = function() {
    console.log('click');
}
console.log(2);
setTimeout(function() {
    console.log(3)
}, 3000)

// 如果是3秒前点击,结果为:1,2,click,3
// 如果是3秒后点击,结果为:1,2,3,click

回调函数交给异步进程处理,如果不点击的话,不会触发单击事件,对应的回调函数就不会放在任务队列中,定时器的回调函数会在3秒后,把回调函数放进队列,所以最后的结果跟单击的时间有关系。(队列是先进先出的)
在这里插入图片描述

主线程不断的获得执行任务这一过程称为事件循环:
在这里插入图片描述

相关文章:

  • 跨行转做产品经理岗位,怎么入门?
  • ssm基于Android系统的学习记录与提醒应用APP(ssm+uinapp+Mysql)
  • 微信小程序入门与实战之阅读列表与setData数据的绑定
  • springboot教室实验室预约系统在线视频点播系统毕业设计毕设作品开题报告开题答辩PPT
  • Go数据结构
  • Vue学习---插槽篇
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • Yii - [新]项目开发流程指南
  • 优秀的你在哪里?《阿里云SLS团队2023校园招聘》
  • 【图像分类】基于matlab多种特征结合支持向量机脑MRI肿瘤分类【含Matlab源码 2149期】
  • 06-使用pytorch实现手写数字识别
  • 高级特效开发阶段学习总结
  • WPF 简单的ComboBox自定义样式。
  • Servlet 规范和 Servlet 容器
  • 切面的优先级、基于XML的AOP实现
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • flask接收请求并推入栈
  • HTTP中GET与POST的区别 99%的错误认识
  • JavaScript 基本功--面试宝典
  • LeetCode算法系列_0891_子序列宽度之和
  • 包装类对象
  • 程序员该如何有效的找工作?
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 后端_MYSQL
  • 聚类分析——Kmeans
  • 入口文件开始,分析Vue源码实现
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • #{}和${}的区别是什么 -- java面试
  • #pragma 指令
  • (C++)八皇后问题
  • (安卓)跳转应用市场APP详情页的方式
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (黑马C++)L06 重载与继承
  • (算法)求1到1亿间的质数或素数
  • (转)jQuery 基础
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .NET中统一的存储过程调用方法(收藏)
  • .net中我喜欢的两种验证码
  • .考试倒计时43天!来提分啦!
  • /bin、/sbin、/usr/bin、/usr/sbin
  • @软考考生,这份软考高分攻略你须知道
  • [ 网络基础篇 ] MAP 迈普交换机常用命令详解
  • [BZOJ] 1001: [BeiJing2006]狼抓兔子
  • [EFI]ASUS EX-B365M-V5 Gold G5400 CPU电脑 Hackintosh 黑苹果引导文件
  • [HDU5685]Problem A
  • [IE9] GPU硬件加速到底是实用创新还是噱头
  • [IE编程] IE中对网页进行截图的编程接口
  • [IM] [Webhook] Webhook实现IM平台机器人
  • [Jquery] 实现温度计动画效果
  • [node]Node.js 模块系统
  • [NOIP2000] 乘积最大
  • [StartingPoint][Tier0]Synced