首页 > 其他分享 >前端代码分析题(选择题、分析题)——JS事件循环分析

前端代码分析题(选择题、分析题)——JS事件循环分析

时间:2024-11-09 16:45:54浏览次数:3  
标签:resolve console log err res 选择题 JS Promise 分析题

 Promise其实也不难-CSDN博客

Promise 的执行顺序分析

Promise 对象的执行是异步的,但其执行器函数内部的代码是立即执行的,而 then方法注册的回调函数则是在 Promise 状态改变后执行的

const myPromise = new Promise((resolve, reject) => {
  console.log('A');
  console.log('B');
});

myPromise.then(() => {
  console.log('C');
});

console.log('D');

A-》B-》D

const newPromise1 = new Promise((resolve, reject) => {
  console.log('A');
  resolve('B');
});
const newPromise2 = newPromise1.then(res => {
  console.log(res);
});
console.log('C', newPromise1);
console.log('D', newPromise2);

A-》C Promise{<fulfilled>:'B'}->D Promise{<pending>}->B

const newPromise = new Promise((resolve, reject) => {
  console.log('A');
  setTimeout(() => {
    console.log("timer start");
    resolve("succeed");
    console.log("timer end");
  }, 0);
  console.log('B');
});
newPromise.then((result) => {
  console.log(result);
});
console.log('C');

事件循环

A-》B-》C-》timer starter->timer end ->succeed

流程解读

  • 当执行到new Promise时,会立即执行Promise构造函数中的执行器函数(executor function),即传递给Promise构造函数的箭头函数
  • 在执行器函数内部,首先打印出'A'
  • 然后,setTimeout被调用,它设置了一个延时为0毫秒的定时器回调。由于setTimeout的回调被放入了宏任务队列(macrotask queue),它不会立即执行,而是等待当前执行栈清空并且微任务队列(microtask queue)也为空时,才会被执行
  • 紧接着,打印出'B'
  • 此时,Promise的执行器函数执行完毕,但Promise对象newPromise状态仍然是pending,因为resolve函数是在setTimeout的回调中调用的,而这个回调还没有执行
  • 紧接着,打印出'C'
  • 事件循环和微任务队列:到目前为止,执行栈已经清空,继续执行微任务队列、宏任务队列中的任务,执行setTimeout()内回调函数。
  • resolve方法会触发在微异步任务队列then()方法,因此先输出栈中数据timer end,再检查队列中待执行的任务resolve

事件循环(Event Loop):事件循环是JavaScript运行时环境中的一个循环机制,它不断地检查调栈用和任务队列。当调用栈为空时,事件循环会首先检查微任务队列,并执行其中的所有任务。只有当微任务队列为空时,事件循环才会检查任务队列,并执行其中的任务。(调用栈-》微任务队列-》宏任务队列)

  • 微任务队列:它专门用于处理如Promiseresolvereject回调、async/await等微任务。微任务的优先级高于宏任务。
  • 宏任务队列:用来存储准备好执行的回调函数,比如setTimeoutsetInterval的回调
  • 调用栈

Promise.resolve().then(() => {
  console.log('outerPromise');
  const innerTimer = setTimeout(() => {
    console.log('innerTimer')
  }, 0)
});

const timer1 = setTimeout(() => {
  console.log('outerTimer')
  Promise.resolve().then(() => {
    console.log('innerPromise')
  })
}, 0)
console.log('run');

run-》outerPromise-》outerTimer-》innerPromise-》innerTimer

 

then方法里面的return语句讲状态改为fulfilled! 

Promise.resolve().then(() => {
  return new Error('error')
}).then(res => {
  console.log("then: ", res)
}).catch(err => {
  console.log("catch: ", err)
})

//打印出then: Error: error

 TypeError: Chaining cycle detected for promise

const promise = Promise.resolve().then(() => {
  return promise;
})
promise.catch(console.err)
//输出TypeError: Chaining cycle detected for promise

promise异常处理

.catch(err=>{console.log(err)}) | .then(res)=>{console.log(res)},(err)=>{console.log(err)}

两个都可以用于处理,那个在先就先处理错误!!!!

Promise.reject('error')
  .then((res) => {
    console.log('succeed', res)
  }, (err) => {
    console.log('innerError', err)
  }).catch(err => {
    console.log('catch', err)
  })

innerError error

  1. Promise.reject('error'):创建一个被拒绝的 Promise,拒绝原因为 'error'

  2. .then((res) => { console.log('succeed', res) }, (err) => { console.log('innerError', err) })

    • 第一个回调函数(处理成功情况的)不会被调用,因为这个 Promise 已经被拒绝。
    • 第二个回调函数(处理拒绝情况的)会被调用,因为它专门用于处理 Promise 被拒绝的情况。因此,会执行 console.log('innerError', err),其中 err 的值为 'error'
  3. .catch(err => { console.log('catch', err) })

    • .catch() 方法是 .then(null, rejectionHandler) 的语法糖,专门用于捕获 Promise 链中未被处理的拒绝情况。
    • 然而,在这个例子中,.then() 方法已经包含了一个处理拒绝的回调函数,因此 .catch() 方法不会被调用。

console.log('catch', err) 也不会被执行, .then() 方法中已经包含了处理拒绝的逻辑

promise .finally()用法

被解决(fulfilled)或拒绝(rejected)之后,执行一些不依赖于 Promise 结果的代码。这个方法返回在JavaScript中,Promise.finally() 方法是一个非常有用的工具,它允许你在一个 Promise 对象一个新的 Promise该 Promise 的解决值(fulfilled value)或拒绝原因(rejection reason)与原始 Promise 相同。

let promise = new Promise((resolve, reject) => {
  // 模拟一个异步操作
  setTimeout(() => {
    resolve('操作成功');
    // 如果改为 reject('操作失败'); 则会触发 catch 回调
  }, 1000);
});

promise
  .then(result => {
    console.log(result); // 操作成功
  })
  .catch(error => {
    console.error(error); // 如果Promise被拒绝,则会打印错误信息
  })
  .finally(() => {
    console.log('清理资源或执行其他不依赖于结果的代码');
    // 这里可以执行一些清理工作,比如关闭数据库连接、清除缓存等
  });
Promise.resolve('A')
  .then(res => {
    console.log('promise1', res)
  })
  .finally(() => {
    console.log('finally1')
  })
Promise.resolve('B')
  .finally(() => {
    console.log('finally2')
    return 'result'
  })
  .then(res => {
    console.log('promise2', res)
  })

//打印promise1 A、finally1、finally2、promise2 B

promise.all()方法

Promise.all() 是 JavaScript 中一个非常有用的方法,它接受一个包含多个 Promise 对象(或可迭代对象,如数组)的可迭代对象,并返回一个新的 Promise。这个新的 Promise 会在所有给定的 Promise 对象都成功解决(fulfilled)后解决,其解决值(fulfilled value)是一个数组,包含了所有原始 Promise 对象的解决值(按相同的顺序)。如果任何一个 Promise 对象被拒绝(rejected),则新的 Promise 会立即被拒绝,其拒绝原因(rejection reason)是第一个被拒绝的 Promise 的拒绝原因。

Promise.all([promise1, promise2, promise3])
  .then((values) => {
    // 所有 Promise 都成功解决后执行这里的代码
    // “!!!values 是一个数组”,包含了 promise1, promise2, promise3 的解决值
  })
  .catch((error) => {
    // 如果有任何一个 Promise 被拒绝,则执行这里的代码
    // error 是第一个被拒绝的 Promise 的拒绝原因
  });
function runAsync(num) {
  return new Promise((resolve) => setTimeout(
    () => resolve(num, console.log(num)), 1000)
  );
}

function runReject(num) {
  return new Promise((resolve, reject) => setTimeout(
    () => reject(`Error: ${num}`, console.log(num)), 1000 * num)
  );
}

Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])
  .then((res) => console.log(res))
  .catch((err) => console.log(err));
  • 1s后 runAsync(1)、runAsync(3)输出1、3
  • 2s号 runReject(2)输出2,状态为reject,promise.all()捕获错误,执行.catch() Error 2
  • 4s后runAsync(4)输出4

 

标签:resolve,console,log,err,res,选择题,JS,Promise,分析题
From: https://blog.csdn.net/m0_55049655/article/details/143643577

相关文章

  • Nuxt.js 应用中的 listen 事件钩子详解
    title:Nuxt.js应用中的listen事件钩子详解date:2024/11/9updated:2024/11/9author:cmdragonexcerpt:它为开发者提供了一个自由的空间可以在开发服务器启动时插入自定义逻辑。通过合理利用这个钩子,开发者能够提升代码的可维护性和调试能力。注意处理性能、错误和环......
  • 基于nodejs+vue只租不卖汽车租赁平台[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于汽车租赁平台的研究,现有研究主要以传统的汽车租赁业务模式为主,包括租赁流程、市场规模、竞争格局等方面的分析。专门针对只租不卖这种特殊运营模式......
  • 基于nodejs+vue职业信息交流平台[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景随着信息技术的飞速发展,职业信息的交流与传播变得日益重要。关于职业信息交流平台的研究,现有研究主要以信息传播的一般性理论为主,专门针对职业信息交流......
  • java ssm 网上蛋糕店 在线蛋糕甜品管理 网上蛋糕管理 源码 jsp
    一、项目简介本项目是一套基于SSM的网上蛋糕店,主要针对计算机相关专业的和需要项目实战练习的Java学习者。包含:项目源码、数据库脚本、软件工具等。项目都经过严格调试,确保可以运行!二、技术实现​后端技术:Spring、SpringMVC、MyBatis前端技术:JSP、HTML、CSS、JavaScri......
  • java ssm 餐厅管理系统 餐馆管理 在线订餐 餐饮管理 源码 jsp
    一、项目简介本项目是一套基于SSM的餐厅管理系统,主要针对计算机相关专业的和需要项目实战练习的Java学习者。包含:项目源码、数据库脚本、软件工具等。项目都经过严格调试,确保可以运行!二、技术实现​后端技术:Spring、SpringMVC、MyBatis前端技术:JSP、HTML、CSS、JavaSc......
  • ssm079基于SSM框架云趣科技客户管理系统+jsp(论文+源码)_kaic
    毕业设计(论文)题目:客户管理系统设计与实现      摘 要现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本客户管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完......
  • node.js毕设校园志愿者服务系统(程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于校园志愿者服务系统的研究,现有研究主要集中在志愿者管理、活动信息发布和反馈等方面,专门针对校园内志愿者服务系统的研究较少。在国内外,志愿者服务......
  • node.js毕设校园订餐系统(程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于校园订餐系统的研究,现有研究主要集中在订餐系统的基本功能实现、用户体验优化等方面,专门针对校园内订餐系统的特殊需求和功能设计的研究较少。在国......
  • 【华为OD技术面试手撕真题】82、环形链表II | 手撕真题+思路参考+代码解析(C & C++ & J
    文章目录一、题目......
  • Moment.js、Day.js、Miment,日期时间库怎么选?
    一直以来,处理时间和日期的JavaScript库,选用的都是Momment.js。它的API清晰简单,使用方便灵巧,功能还特别齐全。大师兄是Moment.js的重度使用者。凡是遇到时间和日期的操作,就把Moment.js引用上。直到有天我发现加载的moment.min.js大小有19.8KB,而我的页面整体大小还不到5KB,Moment......