2024前端面试准备3-JS异步-进阶


1.请描述Event loop(事件循环)的机制。

JS是单线程的,异步需要基于毁掉来实现,event loop 就是异步回调的实现原理。

同步代码,一行一行放在Call Stack执行,遇到异步任务,标记一下让其他线程去处理(定时,网络请求等),其他线程处理完毕就放到callback Queue, 如果Call stack清空(即同步代码执行完),开始执行当前的微任务和微任务引发的微任务,执行完毕微任务队列,然后尝试进行DOM渲染,渲染结束,Event loop开始工作,轮询查找Callback Queue, 如果有则移动到Call Stack执行,然后继续重复上述步骤(永动机一样)。

2.什么是宏任务和微任务,两者有什么区别?

宏任务: setTimeout、setInterval、Ajax、DOM事件

微任务 :Promise、 async/await、

微任务执行时机比宏任务要早,微任务在DOM渲染前触发,宏任务在DOM渲染后出触发。微任务是ES6语法规定,宏任务是由浏览器规定的
3.Promise 有哪三种状态?如何变化?

三种状态:pending\resolved\rejected

pending ->resolved或pending -> rejected,变化不可逆。

resolved 会触发then回调,rejected会触发catch回调,只要回调里面没有报错,无论是then或catch返回的都是resolved状态,报错时会返回rejected状态。
4.async/await Promise的关系

执行async函数,返回的是一个Promise对象;await相当于Promise的then; try...catch可捕获异常,代替了Promise的catch。await后边的内容都可以当作异步回调的内容。

5.手写Promise

  • 初始化&异步调用
  • then链式调用
  • API、resolve、 reject 、all、 race、
js 复制代码
class MyPromise {
  constructor(executor) {
    this.state = "pending";
    this.value = undefined;
    this.onResolveCallbacks = [];
    this.onRejectCallbacks = [];

    const resolve = (value) => {
      if (this.state === "pending") {
        this.state = "fulfilled";
        this.value = value;
        this.onResolveCallbacks.forEach((callback) => callback(this.value));
      }
    };

    const reject = (reason) => {
      if (this.state === "pending") {
        this.state = "rejected";
        this.value = reason;
        this.onRejectCallbacks.forEach((callback) => callback(this.value));
      }
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onResolve, onReject) {
    return new MyPromise((resolve, reject) => {
      if (this.state === "fulfilled") {
        try {
          const result = onResolve(this.value);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      } else if (this.state === "rejected") {
        try {
          const result = onReject(this.value);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      } else {
        this.onResolveCallbacks.push((value) => {
          try {
            const result = onResolve(value);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        });

        this.onRejectCallbacks.push((reason) => {
          try {
            const result = onReject(reason);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }

  catch(onReject) {
    return this.then(null, onReject);
  }
}
相关推荐
东风破_几秒前
LLM 为什么记不住你?无状态、messages 和上下文管理
javascript·人工智能
梨子同志9 分钟前
qiankun
前端
梨子同志18 分钟前
Nginx
前端
梨子同志19 分钟前
NestJS
前端
梨子同志34 分钟前
Next.js
前端
谭光志44 分钟前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
Hilaku1 小时前
前端架构师的克制:什么时候该坚决对新技术说不?
前端·javascript·程序员
陈随易1 小时前
前端项目部署只要30秒
前端·后端·程序员
本末倒置1831 小时前
从 Vue CLI 迁移到 Rsbuild 后,JSX 突然全挂了?一次排查记录
前端
古夕1 小时前
多应用同域部署下 Favicon 异常问题排查与治理
前端·javascript