林大妈的JavaScript进阶知识(二):JS异步行为
JavaScript 是单线程执行的
JavaScript运行在浏览器中。浏览器是多线程的,但只分配了其中一条给JavaScript,作为它的主线程。对于编码者来说,JavaScript是单线程的。因此JavaScript中存在以下几种异步行为:
- 事件绑定(addEventListener)
- 定时器(setTimeout、setInterval)
- AJAX(axios)、fetch
- 所有跟Promise的resolve、reject相关的行为(generator、async/await)
JavaScript 异步执行情况
其中WEB API会执行类似setTimeout的倒数或发送AJAX请求这样的操作,而得到的返回值则会加入Event Queue中等待主栈为空时压栈执行。
练习题目
// 以下的程序将会按照如何的顺序执行?
async function async1 () {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2 () {
console.log('async2')
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
async1()
new Promise((resolve) => {
console.log('promise1')
resolve()
}).then(() => {
console.log('promise2')
})
console.log('script end')
代码的基本分析:
- 第二到第十行,两个异步函数声明,不会输出东西
- 第十二到第二十七行,中间全部是函数执行的代码,可以把它看作主函数
- 第十二行是简单的输出语句
- 十四到十六行是一个setTimeout,通过前面的学习我们知道它会加入宏任务队列
- 第十八行是async1函数的执行,其中有一个async函数的嵌套,它把async2嵌套在了1中的await语句里
- 接着20行是一个Promise对象的声明,声明Promise对象需要传一个名为executor的参数,这个executor是会在声明的时候直接执行的,紧接着23行是一个then回调,通过前面的学习我们知道它会加入微任务队列
- 最后是一个普通的输出语句
因此这题的难点就是在async语句的嵌套中。首先,根据前面的分析,因为前面都是函数声明,不会输出内容,代码会先输出script start,然后setTimeout加入宏任务队列。接下来进入异步函数async1,我们知道,异步函数本质上是generator的语法糖,因此异步函数会一直同步地执行到await语句执行完毕,并且把下面的代码放到微任务队列中,因此代码执行到此还会依次输出async1 start和async2。紧接着创建Promise对象时executor被执行,输出promise1,并把then放入微任务中,最后输出script end。理论上说,到此JS主线程已经执行完毕,也就是主栈中是空的,接下来就要分别看微任务和宏任务队列了。看微任务队列中现在有两个Task,按刚才所说的顺序是先是async1 end,再是promise2,但此处V8引擎版本不同执行情况不同,有的版本是按照队列顺序执行,有的是先执行Promise再执行await后的语句(但新版本的V8引擎是属于先执行Promise这种情况的,因此会输出promise2和async1 end)。这种现象可能是由于底层实现中await转化为promise语句是放在加入队列前还是加入队列后执行的关系,但无论如何它们两个微任务都必会在宏任务前执行,因此最后会输出宏任务的setTimeout。
总结
异步编程需要比较细地掌握它们三个微任务:
- async/await
- Promise
- generator
搞清楚基本的执行顺序即可,也不必要苛求每处都完全正确。
林大妈的JavaScript进阶知识(二):JS异步行为的更多相关文章
- 林大妈的JavaScript进阶知识(一):对象与内存
JavaScript中的基本数据类型 在JS中,有6种基本数据类型: string number boolean null undefined Symbol(ES6) 除去这六种基本数据类型以外,其他 ...
- 林大妈的JavaScript进阶知识(三):HTML5 History API
HTML5中新增了History API,它用于管理浏览器路由跳转的一个url栈.History是window对象的一部分,它也是一个对象,因此称它是BOM(类似DOM,Browser Object ...
- 林大妈的JavaScript基础知识(三):JavaScript编程(2)函数
JavaScript是一门函数式的面向对象编程语言.了解函数将会是了解对象创建和操作.原型及原型方法.模块化编程等的重要基础.函数包含一组语句,它的主要功能是代码复用.隐藏信息和组合调用.我们编程就是 ...
- 林大妈的JavaScript基础知识(三):JavaScript编程(3)原型
在一般的编程语言中,我们使用继承来复用代码,做成良好的数据结构.而在JavaScript中,我们使用原型来实现以上的需求.由于JavaScript专注于对象而摒弃了类,我们要明白原型和继承的确是有差异 ...
- 林大妈的JavaScript基础知识(二):编写JavaScript代码前的一些简单工作
在介绍JavaScript语法前,我们需要知道,学习语法必须要多利用手敲代码来巩固记忆.因此,由于JavaScript的特性,它不能像C++和Java一样独立地编译及运行,我们需要在调试运行JavaS ...
- 林大妈的JavaScript基础知识(三):JavaScript编程(4)数组
数组,是一段线性分配的,具有非常高性能的数据结构.简单地说,数组以连续的空间存储,通过整数地计算偏移量访问其中的元素,将读取修改的时间复杂度降低至O(1),我们称之为猝发式存取.是不是非常期待?没错, ...
- 林大妈的JavaScript基础知识(一):JavaScript简史
前言:做一名Web设计师是一件令人兴奋的事.在Web技术中,JavaScript是一个经历从被人误解到万众瞩目的巨大转变,在历史的冲击中被留存下来的个体.因为JavaScript的引导,Web开发也从 ...
- 林大妈的JavaScript基础知识(三):JavaScript编程(1)对象
1. 对象的简单介绍与一些注意事项 JavaScript中具有几个简单数据类型:数字.字符串.布尔值.null值以及undefined值.除此之外其余所有值(包括数组.函数,甚至正则表达式)都是对象. ...
- JavaScript进阶(二)
什么是事件 JavaScript 创建动态页面.事件是可以被 JavaScript 侦测到的行为. 网页中的每个元素都可以产生某些可以触发 JavaScript 函数或程序的事件. 比如说,当用户单击 ...
随机推荐
- Java网络编程系列之TCP连接状态
1.TCP连接状态 LISTEN:Server端打开一个socket进行监听,状态置为LISTEN SYN_SENT:Client端发送SYN请求给Server端,状态由CLOSED变为SYN_SEN ...
- VMware 完成 27 亿美元的 Pivotal 收购 | 云原生生态周报 Vol. 34
作者 | 汪萌海.王思宇.李鹏 业界要闻 VMware 完成 27 亿美元的 Pivotal 收购 VMware 在 12 月 30 日宣布,已完成 27 亿美元的 Pivotal 收购,同一天 Pi ...
- C# 阿里云查询、删除文件
class Program { static string regionId = "cn-shanghai"; static string accessKeyId = " ...
- 【笔试/面试题】中科创达——9.28(持续更新ing)
1. 线程与进程的区别 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独 ...
- Java 中的四种权限修饰符
* * private: * Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”. * 被其修饰的属性以及方法只能被该类的对象 访问,其子类不能访问,更不能允许跨包访问. * * def ...
- three.js中的事件
以上一篇入门篇为例来简单的设置下3d模型当中的交互事件,上一篇我们已经完成了在3d页面中添加了一个红色球,下面我们给这个球一个点击事件让它Y轴位置上升,再设置一个鼠标移入到球上时让其变色. 1.其实t ...
- .NET为什么要使用异步(async)编程?⭐⭐⭐⭐⭐
.NET为什么要使用异步(async)编程? 有几点坐下笔记 ⭐⭐⭐⭐: 1. 同步方法 static void Main(string[] args) { Console.WriteLine($&q ...
- python 黏包现象
一.黏包 1.tcp有黏包现象 表现两种情况 发送的数据过小且下面还有一个发送数据,这两个数据会一起发送 发送的数据过大,超过最大缓存空间,超出的部分在下一次发送的时候发送 原因: tcp是面向流的, ...
- 「4.0」一个人开发一个App,小程序从0到1,布局
一提到布局这个词,我总是索索发抖,不是因为天冷,而是因为布局的目标实在太宏大.古代想雄霸天下的王,就喜欢布局这个,布局那个,结果硬生生把自己的国家给布局没了.至于是哪个君王,我倒可以非常认真,非常坦诚 ...
- 关于checkbox取值的问题
今天,在做一个小界面的时候,要用到checkbox来判断用户是否选择记住密码. 本来我想这个不是挺简单吗,直接用jquery获取checkbox的checked属性值好了,如下: var rememb ...