异步
今天老师布置了很多的作业,最重要的是每个课程的老师都布置了,而且说作业只有一点,半个小时就做完了。真想让他算算6*3是几个小时。
我在想,要是有两个我就好了。不,得7个,6个做,我去玩。
你可能会问,为啥不同时做呢。
答案就是我是单线程的,只有多线程才能来回切换,做一会语文再做回数学然后返回去再做回语文。
我这么聪明都这样,那电脑这个笨蛋当然不如我了,一次也是只能做一件事
JavaScript 这魂淡更不用说了,一次就只能念一行代码。
可我们的web 一个页面就有很多的交互功能,有一个功能没有进行完,这个笨蛋就只能在那儿一直将这件事做完才能腾出来做另一件事。
终于,我做完了数学,我屁颠的跑去让我妈给我检查一下,我妈见我这么爱学习也是很欣慰。也很乐意的拿起作业,好景不长,三分钟不到一本书从天灵盖落下。我很委屈,做错了也不至于这样啊。
我妈恨铁不成钢的说:我检查的时候你就不能去先去做别的作业吗,看什么电视。原来是偷摸看电视被识破了。
事实证明,千万不要在女人面前玩弄小心思。
苦逼的我只能赶脚的将剩下五门做完了,当我做完的时候,也就只剩下最后一门没有被检查了,我发四我心中没有念叨老师
做完后,自我感觉效率还是蛮高的呀,为了奖励自己我决定给自己做顿饭犒劳一下
以往站在锅前等水热的我,突然想起来,这个时间要是我先去切菜,水热了让锅叫我就行了。这样效率多高呀。我给他起名叫异步。
同步就是一件事一件事的执行。只有前一个任务执行完毕,才能执行后一个任务。
这个同步名字很不好,我们的数据同步也是用这个词,数据同步是让两个地方的数据保持一致。而这儿的同步是一件事做完才能做另一件事。
异步,当然就是一件事没有做完就做另一件事了。
JavaScript 异步
setTimeout(function cbFn(){
console.log('我写在前面,但后执行完');
}, 1000);
console.log('我写在后面,但是先执行完');
在我们浏览器的控制台 (F12) 直接就可以验证了。
setTimeout就是一个异步任务,当JS引擎顺序执行到setTimeout的时候发现他是个异步任务,则会把这个任务挂起,继续执行后面的代码。直到1000ms后,回调函数cbFn才会执行,这就是异步,在执行到setTimeout的时候,JS并不会傻呵呵的等着1000ms执行cbFn回调函数,而是继续执行了后面的代码。
异步的效率是很高的,所以我们的前端采用异步请求来获取数据。
应用到异步的地方有很多,但凡是执行时间长、而又不紧急的东西我们都可以采用异步的机制。
但是最重要的是,没有做完的那件事怎么办呢?咱们比较聪明,能记住哪件事没有做完,但电脑不记得呀,我们怎么告诉他异步的那件事也已经完了呢?
异步处理
JS是如何实现异步操作的呢?
答案就是JS的事件循环机制(Event Loop)。
具体来说:
当JS解析执行时,会被引擎分为两类任务,同步任务(synchronous) 和 异步任务(asynchronous)。
对于同步任务来说,会被推到执行栈按顺序去执行这些任务。
对于异步任务来说,当其可以被执行时,会被放到一个 任务队列(task queue) 里等待JS引擎去执行。
当执行栈中的所有同步任务完成后,JS引擎才会去任务队列里查看是否有任务存在,并将任务放到执行栈中去执行,执行完了又会去任务队列里查看是否有已经可以执行的任务。这种循环检查的机制,就叫做事件循环(Event Loop)。
对于任务队列,其实是有更细的分类。其被分为 微任务(microtask)队列 & 宏任务(macrotask)队列
宏任务: setTimeout、setInterval等,会被放在宏任务(macrotask)队列。
微任务: Promise的then、Mutation Observer等,会被放在微任务(microtask)队列。Event Loop的执行顺序是:
- 首先执行执行栈里的任务。
- 执行栈清空后,检查微任务(microtask)队列,将可执行的微任务全部执行。
- 取宏任务(macrotask)队列中的第一项执行。
- 回到第二步。
注意: 微任务队列每次全执行,宏任务队列每次只取一项执行。
setTimeout(() => {
console.log('我是第一个宏任务');
Promise.resolve().then(() => {
console.log('我是第一个宏任务里的第一个微任务');
});
Promise.resolve().then(() => {
console.log('我是第一个宏任务里的第二个微任务');
});
}, 0);
setTimeout(() => {
console.log('我是第二个宏任务');
}, 0);
Promise.resolve().then(() => {
console.log('我是第一个微任务');
});
console.log('执行同步任务');
结果:
// 执行同步任务
// 我是第一个微任务
// 我是第一个宏任务
// 我是第一个宏任务里的第一个微任务
// 我是第一个宏任务里的第二个微任务
// 我是第二个宏任务
本文探讨了JavaScript中的异步编程概念,通过一个生动的场景比喻解释了同步和异步的区别。讲解了事件循环(EventLoop)的工作原理,包括宏任务和微任务的执行顺序,并通过代码示例展示了异步任务如何影响执行流程。强调了异步处理在提高效率和优化前端性能方面的重要性。

520

被折叠的 条评论
为什么被折叠?



