当前位置: 首页 > news >正文

Promise(微任务)和setTimeout(宏任务)的理解

Promise(微任务)和setTimeout(宏任务)的理解

Promise 和 setTimeout 是 JavaScript 中的两个不同概念,主要用于处理异步操作,但它们的用途和工作方式有所不同。

Promise

  • 定义:Promise 是一个表示异步操作最终完成(或失败)及其结果值的对象。
  • 用途:用于处理异步操作的结果,允许你在操作完成后执行某些代码(通过 .then() 和 .catch() 方法)。
  • 状态:Promise 有三种状态:pending(进行中)、fulfilled(已完成)和 rejected(已拒绝)。
  • 示例:
  const myPromise = new Promise((resolve, reject) => {
      // 异步操作
      setTimeout(() => {
          resolve("操作成功");
      }, 1000);
  });

  myPromise.then(result => {
      console.log(result); // 输出 "操作成功"
  }).catch(error => {
      console.error(error);
  });

setTimeout

  • 定义:setTimeout 是一个用于在指定的延迟后执行代码的函数
  • 用途:用于创建延迟执行的操作,通常用于简单的定时任务。
  • 返回值:返回一个定时器的 ID,可以用来取消定时器(使用 clearTimeout)。
  • 示例:
setTimeout(() => {
      console.log("1秒后执行");
  }, 1000);

总结

  • Promise 主要用于处理异步操作的结果,而 setTimeout 用于延迟执行某段代码。
  • Promise 可以链式调用,便于处理多个异步操作的结果,而 setTimeout 只是简单的延迟执行。

事件循环与帧的关系

  1. 事件循环:
  • JavaScript 是单线程的,意味着它一次只能执行一个任务。
  • 事件循环负责管理执行栈、微任务队列和宏任务队列之间的调度。
  1. 帧的概念:
  • 在浏览器中,帧(frame)通常指的是每次重绘(repaint)或重新渲染的周期。
  • 一帧的时间通常是 16.67 毫秒(在 60 FPS 的情况下),这是浏览器更新页面的频率。

当前执行栈

  1. 栈的结构
  • 当前执行栈是一个后进先出(LIFO, Last In First Out)的数据结构。
  • 当一个函数被调用时,它会被推入栈中;当函数执行完毕后,它会从栈中弹出。
  1. 执行过程
  • 当 JavaScript 引擎执行代码时,它会将全局上下文推入栈中。
  • 当一个函数被调用时,新的执行上下文会被创建并推入栈中。
  • 当函数执行完成后,它的上下文会被弹出,控制权会返回到调用该函数的上下文。

微任务

  • 定义:微任务是指在当前执行栈完成后立即执行的任务。它们通常用于处理 Promise 的回调。
  • 执行顺序:微任务会在当前宏任务完成后、下一个宏任务开始之前执行。也就是说,所有的微任务会在当前宏任务的所有代码执行完毕后立即执行。
  • 常见的微任务:
  1. Promise 的 .then() 和 .catch() 回调
  2. MutationObserver 的回调

宏任务

  • 定义:宏任务是指在事件循环中排队的任务,通常是较大的任务,可能会涉及到 I/O 操作、定时器等。
  • 执行顺序:宏任务会在微任务执行完毕后执行。每次事件循环的迭代都会从宏任务队列中取出一个任务执行。
  • 常见的宏任务:
  1. setTimeout
  2. setInterval
  3. I/O 操作(如网络请求)

事件循环的执行顺序

  1. 执行一个宏任务(例如,主线程中的代码)。
  2. 执行所有的微任务(例如,Promise 的回调)。
  3. 如果有下一个宏任务,继续执行下一个宏任务。
  4. 重复步骤 2 和 3,直到所有任务都完成。

也就是说Promise中的任务不会立即执行,而是在当前任务队列都执行完毕后才会执行,但是确实是在同一帧中执行的,若耗时过长也会卡进程。
而setTimeOut任务是把事件分发到下一帧去执行的,可以分帧执行减少每帧运行压力。

http://www.dtcms.com/a/123058.html

相关文章:

  • P1825 [USACO11OPEN] Corn Maze S【java】【AC代码】
  • C++:函数模板类模板
  • 什么是巨型帧Jumbo Frames?云服务器开启巨型帧有什么用?
  • 2025年4月9日-华为暑期实习-第二题-200分
  • 动态类生成 / 加载机制(更新)
  • Java集合框架:核心接口与关系全解析
  • springboot中测试python脚本:ProcessBuilder
  • 如何使用 PyTorch 和 EfficientNet 创建一个 AI 游戏外挂[特殊字符]
  • 基于MCP协议调用的大模型agent开发03
  • InnoDB 事务更新过程深度剖析:原理、流程与优化
  • 前端-vue2核心
  • 如何用postman做接口自动化测试?
  • Seata框架,如何保证事务的隔离性?
  • 【时时三省】(C语言基础)用switch语句实现多分支选择结构
  • 【运维 | 硬件】服务器中常见的存储插槽类型、对应的传输协议及其特性总结
  • 环信鸿蒙版 UIKit 快速上手指南
  • 如何将多个Word文档合并
  • 【HTML】动态背景效果前端页面
  • 基于 Qt4 的图片处理工具开发(二):增加对比度调节、界面布局优化、多线程操作
  • 初识Redis · 简单理解Redis
  • 使用注解@RequestBody变红的解决问题
  • 【spark认任务提交】配置优先级顺序
  • 银河麒麟v10(arm架构)部署Embedding模型bge-m3【简单版本】
  • 【C++进阶】关联容器:multimap类型
  • 学习海康VisionMaster之四边形查找
  • 【达梦数据库】bash: /dev/null: Permission denied
  • 使用stm32cubeide stm32f407 lan8720a freertos lwip 实现tcp客户端、服务端及网络数据转串口数据过程详解
  • SQL 关键字
  • 低硬件资源微调预训练Mamba模型的方法
  • 在 transformers 中,return_tensors=‘pt‘ 里的 pt 是什么 tf,np