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);
  }
}
相关推荐
飞川撸码几秒前
web vue 项目 Docker化部署
前端·vue.js·docker·运维开发
默默无闻的白夜3 分钟前
【Vue】初学Vue(setup函数,数据响应式, 脚手架 )
前端·javascript·vue.js
萌萌哒草头将军8 分钟前
⚡⚡⚡Rstack 家族即将迎来新成员 Rstest🚀🚀🚀
前端·javascript·vue.js
江城开朗的豌豆17 分钟前
Proxy:JavaScript中的'变形金刚',让你的对象为所欲为!
前端·javascript·面试
江城开朗的豌豆25 分钟前
JavaScript中的instanceof:你的代码真的认识'自家孩子'吗?
前端·javascript·面试
JinSo27 分钟前
create-easy-editor —— 快速搭建你的可视化编辑器
前端·前端框架·github
蒟蒻小袁29 分钟前
力扣面试150题--课程表
算法·leetcode·面试
coding随想32 分钟前
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
javascript
Watermelo61736 分钟前
【前端实战】如何让用户回到上次阅读的位置?
前端·javascript·性能优化·数据分析·哈希算法·哈希·用户体验
张风捷特烈43 分钟前
每日一题 Flutter#7,8 | 关于 State 两道简答题
android·flutter·面试