JS执行长任务时如何让出控制权?分享1段优质JS代码片段!

Hi,这里是前端后花园,每天学习一个 JS 片段,涨涨知识🧀!今天带来的是JS执行长任务时如何让出控制权。

代码片段

function breakItUp () {
  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

async function superLongTaks() { 
  console.log('开始做一些事情...');  
  // 异步等待breakItUp中的Promise解决  
  await breakItUp(); 
  console.log('完成做一些事情,现在做更多事情...');  
  // 这里可以添加更多需要异步等待的代码  
}

superLongTasks();

分享原因

  1. JavaScript 中的“长任务”指的是那些执行时间过长,会阻止主线程响应(UI线程、事件循环)、用户交互,影响用户体验;

  2. JavaScript 中的“长任务”需要分解成多个任务,以便浏览器有足够的空间来响应任何待处理的交互;

  3. 同时通过在多个任务执行间隙将控制权“交还”给浏览器,让其运行可能堆积的任何重要任务(页面渲染、用户输入等),保证页面交互流畅。

代码解析

  1. 创建 Promisenew Promise(resolve => setTimeout(resolve, 0)) 创建了一个新的 Promise 对象。这个 Promise 将在 setTimeout 的回调函数被调用时resolve

  2. 设置 setTimeoutsetTimeout 的回调函数并不是在达到延迟后立即执行,而是会在当前执行栈清空、所有微任务完成后,作为下一个宏任务执行;

  3. 控制权交还事件循环:在 await 等待 Promise 解决的过程中,JavaScript 运行时将控制权交还给事件循环。此时,事件循环会检查并执行任何待处理的微任务,然后处理任何新的宏任务,比如其他 setTimeoutsetInterval、I/O 回调等。由于创建的 Promise 依赖于 setTimeout,它会等待直到下一个宏任务执行周期。

  4. 执行 await 后代码:下一个宏任务时promiseresolve后,执行后续代码逻辑

让出控制权会执行什么

await 等待期间,会执行所有在事件循环中排队的微任务(如 Promise.thenMutationObserver 回调等)以及下一个宏任务队列中的任务(如 setTimeoutsetInterval 回调等)。

如果代码中没有其他微任务或宏任务等待执行,浏览器可能会利用这段时间进行页面渲染、处理其他事件等。

但是,由于 setTimeout 的特性,即使设置的延迟为 0Promiseresolve也会延迟到下一个宏任务周期,从而允许浏览器在此期间执行其他任务,实现让出控制权。


这里是JS代码片段系列,记录开发过程常见代码片段,往期精选JS代码片段:

四个初始化 JavaScript Array数组方法及性能对比

JS片段:如何将文本复制到剪贴板

JS片段:如何计算 SHA-256 hash值

如何获取字符串的字节长度?分享1段优质JS代码片段!

如何用JS实现sleep函数?分享1段优质JS代码片段!

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端后花园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值