聊聊前端面试之输出顺序
栏目: JavaScript · 发布时间: 6年前
内容简介:春节后,新一轮跳槽风暴不知道能否吹暖今冬的裁员寒冬。然而,职场现状就是越来越多的小公司也在效仿各大互联网牛场面试要求,对于底层知识要求越来越深,管他用着用不着的,先面了再说。本篇跟大家聊聊面试常见题型之显示顺序问题。注:本篇分析为在浏览器环境中排序显示。Nodejs编程是全异步,事件引擎为libuv。
春节后,新一轮跳槽风暴不知道能否吹暖今冬的裁员寒冬。然而,职场现状就是越来越多的小公司也在效仿各大互联网牛场面试要求,对于底层知识要求越来越深,管他用着用不着的,先面了再说。本篇跟大家聊聊面试常见题型之显示顺序问题。
注:本篇分析为在浏览器环境中 排序 显示。
Nodejs编程是全异步,事件引擎为libuv。
一、JavaScript运行机制
关于运行机制聊四个关键点:
- 单线程:同一时间只能解决一件事,是JS核心特征。JS为什么不能多线程?因为JS是浏览器脚本语言,主要用于用户交互与DOM操作;
- 任务类型: 同步任务 与 异步任务 。同步任务是主线程上的排队等待解决的任务,只有完成一项任务,才可以进行下一个任务;异常任务,不进入主线程任务,而是进入“任务队列”,只有主线程的任务完成后,才会召唤“任务队列”上任务并执行;
- 任务队列:是一个事件队列,I/O设备完成一项任务,就会在“任务队列”里添加一个事件。 注意,必须I/O设备完成有结果,才会进入到“任务队列”;
- 事件循环(Event Loop):主线程不断的循环从“任务队列”读取事件的运行机制。
二、任务的阶级斗争
JavaScript任务运行机制图
第一阶级:同步任务
1、皇帝豪饮两碗鹿血,问有个叫EventLoop的公公,今晚谁来陪睡,EventLoop掐指一算,正宫几个“同步任务“娘娘都送过礼,我就按照送礼顺序来给她们安排吧。
同步任务优先执行,先进先出。
第二阶级:异步任务(微任务)
2、几晚过后,所有送过礼的“同步任务”娘娘轮流服侍皇帝一遍。如此同时,秀宫的宫女们忙着化妆整容。原来,宫里有个不成文的规定,只有收拾好自己的宫女才可以排队等待皇帝的召唤,到时候公公EventLoop会按照排队次序向皇帝安排服侍。
3、什么时候才轮到宫女们服侍呢?是“同步任务”娘娘们服侍一遍后,毕竟公公EventLoop为了保护自己的饭碗,得让皇帝不断尝鲜。
同步任务执行的同时,异步任务在事件栈完成后,异步任务进入“任务队列”;
事件循环(Event Loop)驱使主线程在全部同步任务完成后,从“任务队列”读取事件,如此不断循环;
任务队列执行先进先出;
第三阶级:异步任务--定时器(宏任务)
4、在秀宫有两个宫女姓SetTimeout和setInterval,人老珠黄,虽然化妆技术还可以,也送过了礼,无奈确实不上档次,负责秀宫的公公就让她俩排在了所有宫女的后边,等着呗。
5、这俩宫女终于看到希望了,可谁知又来一批年轻漂亮的秀女,怎么办,等着呗。
6、终于,前前后后好几批年轻秀丽的宫女们服侍完皇帝,轮到这两位了,按照老规则,谁先来的谁优先,俩人对视苦笑,回头一看,又来几个姓SetTimeout和setInterval的宫女...
同时嵌套在异步操作的任务,会将嵌套在异步的下一次任务队列中;
定时器任务添加到任务队列的尾部;
三、案例分析
基于今日头条的面试题改造
async function async1() { console.log(1) await async2() console.log(2) return await 3 } async function async2() { console.log(4) } setTimeout(function() { console.log(5) }, 0) async1().then(v => console.log(v)) new Promise(function(resolve) { console.log(6) resolve(); console.log(7) }).then(function() { console.log(8) }) console.log(9)复制代码
- 从代码第一行开始,异步函数async1、async2构建完未执行。
-
按照代码顺序,首先该执行的应该是
setTimeout
,怎奈又不是正宫,长得又不秀丽,只能在任务队列最后等着。 -
运行到
async1.then()
时,async1返回一个Promise
对象(异步函数其实是封装的Promise.resolve()
,Promise
对象是一个构造函数),所以在执行async1时,首先将非resolve、reject函数加入主线程,上题中首先执行console.log(1)
和await async2
,
输出1,4
。感觉await挺孙子的,执行完自己的函数就跳出来async
函数。
- 继续看,异步函数async1的then执行这个时候进入事件栈,因为还在等待异步函数async1返回值,等着吧。
-
继续向下执行遇到真正的
Promise
对象了,二话不说,执行下先,console.log(6)
、console.log(7)
直接加入到主线程,输出6,7
。同时将异步函数console.log(8)放在储秀宫,虽然属于第二阶级,起码还是第二阶级的老大么。 -
单纯的console.log(9)说,咱也是第一阶级的,虽然最后一位,侍架一晚,输出了
9
。
-
同步人物结束了,Event Loop开始召唤任务队列,console.log(8)说我是秀女中的第一位,好,就你了。于是,生出了
8
。 -
setTimeout翘首以盼,谁知,执行完本轮又跳到到异步函数async1,率先看到了
console.log(2)
,所以输出了2
。 -
紧接着,又遇到了
await
了,还好,结束了,返回的值扔给了async
的异步函数,得到了值,抓紧时间执行,得到结果了,终于可以进入任务队列,这时主线程也是空的,执行下结果吧,输出了3
。 -
所有微任务结束了,该宏任务大展拳脚了,setTimeout输出了值,
5
。
以上试题分析完毕,输出结果顺序为: 1,4,6,7,9,8,2,3,5
。
四、最后
以上是个人对于任务执行顺序的理解,如理解有误,希望大神多多指教。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C#图解教程
索利斯 (Daniel M.Solis) / 姚琪琳、苏林、朱晔 / 人民邮电出版社 / 2013-7-1 / CNY 89.00
本书是广受赞誉的C# 图解教程的最新版本。作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式、朴实简洁的文字,并辅以大量表格和代码示例,全面、直观地阐述了C# 语言的各种特性。新版本除了精心修订旧版内容外,还全面涵盖了C# 5.0 的新增特性,比如异步编程、调用者信息、case 表达式、带参数的泛型构造函数、支持null 类型运算等。通过本书,读者能够快速、深入理解C#,为自己的编程生涯......一起来看看 《C#图解教程》 这本书的介绍吧!