• javascript中的异步 macrotask 和 microtask 简介


    javascript中的异步 macrotask 和 microtask 简介

    什么是macrotask?什么是microtask?
    在理解什么是macrotask?什么是microtask之前,我们先来看看javascript中的事件循环机制,先看如下面一段代码:

    console.log(1);
    setTimeout(function(){
      console.log(2);
    }, 0);
    console.log(3);

    很明显 上面运行的结果是 1,3,2;
    上面代码 setTimeout的延时为0,可以理解为setTimeout为异步函数调用,这是因为javascript是单线程的,主线程拥有一个执行栈以及一个任务队列
    ,主线程会依次执行代码,当遇到异步函数时候,会先将该函数入栈,所有主线程函数运行完毕后再将异步函数出栈,直到所有的异步函数执行完毕即可。

    Macrotasks和Microtasks

    Macrotasks和Microtasks 都属于上述的异步任务中的一种,他们分别有如下API:
    macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
    microtasks: process.nextTick, Promise, MutationObserver

    setTimeout的macrotask, 和 Promise的microtask 有哪些不同,先来看下代码如下:

    console.log(1);
    setTimeout(function(){
      console.log(2);
    }, 0);
    Promise.resolve().then(function(){
      console.log(3);
    }).then(function(){
      console.log(4);
    });

    上面的代码输出的是 1, 3, 4, 2;

    如上代码可以看到,Promise的函数代码的异步任务会优先于setTimeout的延时为0的任务先执行。
    原因是任务队列分为 macrotasks 和 microtasks, 而promise中的then方法的函数会被推入到microtasks队列中,而setTimeout函数会被推入到macrotasks
    任务队列中,在每一次事件循环中,macrotask只会提取一个执行,而microtask会一直提取,直到microsoft队列为空为止。
    也就是说如果某个microtask任务被推入到执行中,那么当主线程任务执行完成后,会循环调用该队列任务中的下一个任务来执行,直到该任务队列到最后一个任务为止。而事件循环每次只会入栈一个macrotask,主线程执行完成该任务后又会检查microtasks队列并完成里面的所有任务后再执行macrotask的任务。

    Microtask的应用:
    为啥要用microtask? 根据 HTML Standrad, 在每个task运行完以后,UI都会重新渲染,那么在microtask中就完成数据更新,因此当前task
    结束就可以得到最新的UI了。反之:如果新建一个task来做数据更新的话,那么渲染会执行两次。知乎如下回答(https://www.zhihu.com/question/55364497/answer/144215284)

  • 相关阅读:
    动态规划 01背包问题
    日常水题 蓝桥杯基础练习VIP-字符串对比
    本博客导航
    2019 ICPC 南昌 (C E G L)
    [模板]线段树
    [模板]手写双端队列(或普通队列)
    2019 ICPC Asia Yinchuan Regional (G, H)
    与超级源点与超级汇点相关的两题POJ 1062, HDU 4725
    [模板]链式向前星
    [总结]关于反向建图
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/7675185.html
Copyright © 2020-2023  润新知