Js的异步实现
JS中的任务分为 同步任务 和 异步任务。
首先看一下两种任务:
同步任务
同步任务(synchronous):在主线程上排队的任务,只有前一个执行完毕才能执行下一个。
先来看一段示例代码:
console.log('aaaa');
console.log('ssss');
console.log('dddd');
//那么执行结果:aaaa ssss dddd
做前端的应该都知道Js是单线程的顺序执行,所以输出结果无疑是顺序输出。
console.log('aaaa');
alert('ssss')
console.log('dddd');
// aaaa 弹窗ssss dddd
再看这段示例,有alert的存在,如果我们不关掉alert弹框,是不会执行"dddd"的,所以就阻塞了
异步任务
异步任务(asynchronous):在任务队列中执行,只有等待主线程任务执行完毕,任务队列请求主线程开始执行,进入主线程执行。
“setTimeout()”相信大家都不陌生。
console.log('aaaa');
setTimeout(()=>{
alert('ssss')
},1000)
console.log('dddd');
//输出结果:aaaa dddd 弹窗ssss
这次的输出并没有因为alert的弹出框而阻塞后面代码的执行。
同步和异步的区别
同步会阻塞程序的执行;
异步不会阻塞程序的执行;
异步的实现方式
- 宏任务: setTimeout,setInterval,ajax 等等
- 微任务: Promise,async,await 等等
注:微任务执行时机比宏任务早!
宏任务的执行示例:
示例1:setTimeout
console.log('aaaa');
setTimeout(() => {
console.log('bbbb');
}, 100)
setTimeout(() => {
console.log('ccccc');
}, 101)
console.log('dddddd');
setTimeout(() => {
console.log('eeeeee');
}, 50)
//输出:aaaa dddddd eeeeee bbbb ccccc
示例2:setTimeout
console.log('aaaa');
setTimeout(() => {
console.log('bbbb');
}, 0)
setTimeout(() => {
console.log('ccccc');
}, 0)
console.log('dddddd');
setTimeout(() => {
console.log('eeeeee');
}, 0)
//输出:aaaa dddddd bbbb ccccc eeeeee
示例3:Promise
console.log('aaaaa');
setTimeout(() => {
console.log('ddddddd');
}, 100)
new Promise((resolve, reject) => {
console.log('bbbbb');
resolve()
})
//输出:aaaaa bbbbb ddddddd
此示例就遵循了我们上面说的 “微任务的执行时机比宏任务早”;
异步执行顺序
第一种情况(没有微任务的前提):主线程任务 =====》主线程中的宏任务
第二种情况(宏任务微任务同时存在): 主线程任务 =====》主线程中的微任务 =====》主线程中的宏任务
如下图: