最近学事件循环这一块越学越晕,网上看到说法千奇百怪,什么都有。主要有以下几个疑惑,希望有大佬能够解答。
- 什么是任务?
- 看到有文章说,任务是代码块开始执行/函数栈的入口,除了script整体代码,入口都是回调函数。这个说法对吗?按这个说法,除了script标签,其他任务不都是异步任务了吗?那还有同步任务这个概念吗?
- 如何区分宏任务和微任务?
最近学事件循环这一块越学越晕,网上看到说法千奇百怪,什么都有。主要有以下几个疑惑,希望有大佬能够解答。
请不要将ECMAScript规范中的job和HMLT标准中的task搞混,虽然这两个都是抽象概念
https://262.ecma-internationa...
https://262.ecma-internationa...
event loop的实现来源于HMLT标准
https://html.spec.whatwg.org/...
https://html.spec.whatwg.org/...
当执行一段js的时候,会产生一个或者多个job,这些job实现这段js的计算,这是从js引擎角度来说的。
而HTML标准说的task,是浏览器要执行的任务,可能包含了需要执行js,也可能需要调度其它线程或进程处理,比如xhr的send,不仅有js的执行,还有http的创建、发送、监听
和代码关系更大的其实是job,但job和task都是抽象概念,没必要非得对应上哪一段js
“任务”这个词本身就是自定义的,A文章里的任务和B文章里的任务可能根本不是一个东西。宏任务和微任务更是一种相对的描述,纠结这个的话只会越来越晕。
关于同步和异步是有比较标准的说法的,简单来说同步是指顺序执行,异步是非顺序执行的。
同步有一个问题就是你无法离开,所以可能浪费时间。
// 同步伪码
1 开启热水壶
2 等待5分钟
2.1 1秒过去了
2.2 2秒过去了
2.5*60 300秒过去了
3 关闭热水壶
所以,产生了异步方式
// 异步伪码
1. 开启热水壶
2. 设定一个5分钟的闹钟
3. 爱干啥干啥去吧
// 然后再另一个平行空间里
1. 1秒过去了
2. ...
3. 5分钟过去了
4. 响铃
// 主空间的你听到了平行空间传来的铃声
1. 暂停正在进行的事情
2. 关闭热水壶
有些人会把上面的异步行为解释为“任务”,因为虽然你中间离开了,但是烧水这件事情也完成了,所以称为“异步任务”。但其实一毛钱关系也没有,只是3件事情顺序发生之后偶然的完成了任务而已。希望最后一段伪码你能理解。
// 以下假定定时完成时其功能也执行完成了
// A
1. 开电饭锅
2. 闹表定时10分钟
// B
1. 开热水壶
2. 闹表定时5分钟
// C
1. 开热水器
2. 闹表定时15分钟
// 事件侦听-闹表响
1. 检查电饭锅里的饭熟了吗,如果熟了关闭电饭锅
2. 检查热水壶里的水开了吗,如果开了关闭热水壶
3. 检查热水器里的水到70度了吗,如果到了关闭热水器
什么是任务?
JS 是一门“事件驱动”的语言。假如你注册了一件需要处理的事件,例如用户点击事件,那么你肯定是要写代码来处理这些事件的,这些代码就同属于一个“任务”。
需要注意的一点是:假如你在一个任务里注册了另一个事件,处理另一个事件的代码就不属于当前的“任务”了。
看到有文章说,任务是代码块开始执行/函数栈的入口,除了script整体代码,入口都是回调函数。这个说法对吗?按这个说法,除了script标签,其他任务不都是异步任务了吗?那还有同步任务这个概念吗?
- 任务是代码块开始执行/函数栈的入口?当然不是,与我上面一个解释是相悖的。但是这么理解其实也可以,尤其对于新手而言,如何区分一组同步代码并非易事,干脆只讨论它们的入口,你看到的那篇文章想必是面向新手的,也就是试图在不引入完整事件循环机制的前提下解释任务的含义,当然,这样做必然是越解释越乱——倒也不是作者说法的问题,而是读者从别的地方接受了一些根深蒂固的概念,一时转变不过来。
- 除了script标签,其他任务不都是异步任务了吗?那还有同步任务这个概念吗?同步和异步其实是描述代码块/函数之间的关系的,而不是描述任务的,自然也就不存在同步任务、异步任务的说法。
如何区分宏任务和微任务?
本着记少不记多的原则,记住哪些是微任务就行了,但是你既然在学习事件循环机制,要理解两种任务在循环中的执行时机的差异。
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答5.2k 阅读✓ 已解决
1 回答3.4k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
script
标签代码块、异步代码块(ajax
、setTimeout
之类的)。不是指{}
中的内容哈。Promise
之类),其他的都是宏任务