首先一定要明确一点:JS 是单线程
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得
不一直等着。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的
感觉,从而导致用户的使用体验不佳。继而就有了“同步任务和异步任务”
同步任务与异步任务
1. 同步任务(synchronous)
又叫做非耗时任务,指的是在主线程上排队执行的那些任务,只有前一个任务执行完毕,才能执行后一个任务。
2. 异步任务(asynchronous)
又叫做耗时任务,不进入主线程、而进入”任务队列”的任务,当主线程中的任务运行完了,才会从”任务队列”取出异步任务放入主线程执行。
异步任务又分为宏任务和微任务
执行顺序:同步代码 -> 微任务 -> 宏任务
| 宏任务 | 微任务 |
|---|---|
| 定时器(setTimeout,setInterval,setImmediate) | Promsie(async/await) |
| script | process.nextTick |
| ajax | MutationObserver |
| nodejs中的fs I/O操作 |
代码示例:
到这有个疑问了:为什么6会在2和3之前输出呢?
首先问出这个问题的小伙伴很多都没懂then里面的方法是什么时候被塞到微任务队列里面去的;
规范上说(大概这么个意思):只有上一个then promise 的状态被改成完成态,接下来的链式then才会被调用,调用的时候回调
作为微任务 塞到微任务队列里面去;
async,await阻塞顺序
async,await:是建立在 promise 的基础上的 ,一般成对出现。当一个函数前加了async,就表示这个函数里很大可能有异步函数,而在第一个await表达式出现之前,异步函数内部的代码都是按照同步方式执行的。await所在表达式是同步的。
await会阻塞其所在表达式中后续表达式的执行(在和await在同一函数内但在await后面的代码会被阻塞,形成类似微任务的存在)
例: