JavaScript 的异步新道路 ES11 宣布!!

阅读时长 6 分钟读完

JavaScript 的异步新道路 ES11 宣布!!

ES11 是 JavaScript 的新版本,其中最重要的变化是异步编程方面的新特性。在这个版本中,出现了微任务和宏任务这两个概念。在底层处理异步任务之前,先来了解一下它们的含义和作用,以及如何在实际编程中应用它们。

什么是微任务和宏任务?

在 JavaScript 中,异步任务可以分为两类:宏任务和微任务。简单来说,宏任务就是浏览器自身的任务,通过 setTimeoutsetInterval 等方法添加到任务队列中的任务就称为宏任务。而微任务是在宏任务执行完成后,在当前任务执行结束前需要完成的任务,主要有 Promise.thenObject.observeMutationObserver 等方法。

我们可以将宏任务理解为主线程中的任务,而微任务是主线程内部的任务。微任务的执行顺序优先于宏任务,也就是说,在一个宏任务执行的期间,如果有微任务需要执行,那么这些微任务会优先被执行。

微任务和宏任务的执行顺序

在 JavaScript 中,任务的执行顺序遵循一个简单的规则:同等级的任务,按照它们被添加到任务队列中的顺序被执行,而不是由它们的类型(微任务或宏任务)来判断。

假设当前主线程执行的是一个宏任务,这个宏任务中又包含了若干微任务。这时候,程序会先执行这些微任务,然后再去执行下一个宏任务。

例如,下面的代码中,我们会发现先执行了 Promise 中的两个微任务,再执行 setTimeout 中的宏任务:

输出结果:

微任务和宏任务的使用场景和指导意义

  1. 微任务使用场景

微任务通常用于需要立即执行的任务,比如显示加载动画、异步状态的更新等等。

使用微任务的好处是,因为它们的执行顺序不受宏任务的影响,所以可以确保它们及时地被执行。

  1. 宏任务使用场景

宏任务通常用于需要等待一段时间后才能执行的任务,比如定时器、I/O 操作、事件监听等等。

使用宏任务的主要好处是,它们可以确保当前任务的执行不会超时,从而使得浏览器能够在循环调用中合理分配 CPU 资源,保证不阻塞页面渲染。

示例代码

在下面的例子中,我们使用 Promise 作为微任务,根据需要来决定使用 setTimeout 还是 setInterval 来创建宏任务。在定时器到达之前,我们可以将某些 UI 组件设置为不可用状态,从而避免用户重复点击:

-- -------------------- ---- -------
-------- ------------- -
  ----- ------ - ---------------------------------
  -------------------- - -------
-

-------- ------------- -
  ----- ------ - ---------------------------------
  -------------------- - ------
-

-------- ------------------- -
  -------------

  ---------------
    -------------- -- ----------------
    ---------- -- -
      --------------
      -------------
    --
    ------------ -- -
      --------------
      -------------
    --
-

-------- -------------- -
  ----- --------- - ------------------------------------
  ------------------- - ----
-

-------- -------------- -
  ----- ----- - --------------------------------
  ------------------- - -------
-

-------- ---------------- -
  ----- ------- - ---------------------------------------
  --- ---- - - -- - - --------------- ---- -
    ------------------- - ----
  -
-

-------- --------------- -
  ----- ------- - ---------------------------------------
  --- ---- - - -- - - --------------- ---- -
    ------------------- - -----
  -
-

-------------------------------------------------------------- -- -- -
  ----- -------- - ----------------------------------------------
  ----------------
  ------------- -- -
    -------------------
    ---------------
  -- -----
--
展开代码

在上面的代码片段中,我们使用 showLoadinghideLoading 函数控制显示和隐藏加载动画。在 fetchData 函数中,我们使用 Promise 来将更新 UI 和隐藏加载动画的操作添加为微任务。

disableButtonsenableButtons 函数中,我们使用 for 循环将按钮元素的 disabled 属性设置为 truefalse,以确保在数据加载期间不会发生用户的重复点击。

在事件监听器中,我们调用 disableButtons 函数,将所有按钮设置为不可用,然后使用 setTimeout 创建一个 2 秒后触发的宏任务,在宏任务执行之前,用户不能再次使用按钮进行数据加载。

在宏任务触发的回调函数中,我们调用 fetchData 函数进行数据加载,然后使用 enableButtons 函数使得按钮重新可用。

总之,微任务和宏任务的使用场景不同,但都可以帮助我们更好地实现异步编程。熟练掌握它们的概念和使用方法,有助于我们更加高效地编写复杂的 JavaScript 代码。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67b96e04306f20b3a67cbc21

纠错
反馈

纠错反馈