林大妈的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 函数或程序的事件. 比如说,当用户单击 ...
随机推荐
- kmp算法初步理解
123456789 abbdaxnds Next 01212 第三位看第二位b,第二位和第三位相同,都是b,所以第三位的next是第二位的next加1,即1+1=2 第四位看第三位b,第四位d与第 ...
- 体验.NET Core 命令行应用程序-CommandLineUtils
前言 在我们开发中可能需要设计一次性应用程序,这些实用程序可以利用接近原始源代码的优势,但可以在与主Web应用程序完全独立的安全性上下文中启动.具体在 [管理过程](https://12factor. ...
- JSON的学习与使用
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- 牛客暑期ACM多校 第七场
链接:https://www.nowcoder.com/acm/contest/145/C来源:牛客网 C .题目描述 A binary string s of length N = 2n is gi ...
- kmp-最小子串回文次数
poj 2406 Given two strings a and b we define a*b to be their concatenation. For example, if a = &quo ...
- 定时器之Quart.net(2)
第一步:Install-Package Quartz namespace ProjectEdb { class Program { static void Main(string[] args) { ...
- EasyExcel 自定义单元格式的问题。
最近在做一个关于性能测试管理系统,一个新的需求,需要导出测试报告,直接使用了ali的封装的EasyExcel,但是在复杂头与一些样式,就缺少了自定义的灵活性,在官方demo中没有找到很好的解决方法. ...
- 美食家App开发日记2
操作Android内置数据库失败...由于个人愚钝,按照书上所讲,一步一步写,中间出了一系列问题,有些功能在网上查了很多解决方案仍无法解决,导致无法使用. 感觉Android操作很难...
- 电脑开机后多了OneKey Ghost启动选项怎么解决
原文地址:http://www.xitongcheng.com/jiaocheng/dnrj_article_18745.html 大多数用户在使用OneKey Ghost安装电脑系统后,会在开机启动 ...
- 06hive企业调优
一.Fetch抓取 Fetch抓取是指,Hive 中对某些情况的查询可以不必使用MapReduce计算. 在 hive-default.xml.template 文件中 hive.fetch.task ...