Yuan的博客
EN

事件循环 、Promise、Async/Await

请说明浏览器中的事件循环 (Event Loop)

  • 事件循环不是 JS 本身的功能,而是由 浏览器或 Node.js 的执行环境提供的调度机制。JS 本身只有同步执行、单线程。
  • 事件循环 (Event loop) 的组成:主线程依序执行同步代码 → 放进 Stack,遇到异步任务(例如 setTimeout)→ 浏览器交给 Web API 处理,异步任务完成后 → 回调函数放到任务队列 Queue,当 Stack 为空→ Event Loop 把 Queue 里的第一个任务丢进 Stack,重复步骤 1–4→ 这就是 事件循环 Event Loop。
  • Stack 执行同步,Queue 存放异步,Event Loop 负责把异步回调送回 Stack 执行。
  • 异步任务顺序:在一次事件循环中,宏任务一次只提取一个,执行完成后,会先去看微任务列队,不断提取到执行栈中直到微任务列队为空,再回去执行宏任务。
    • 宏任务 (Macro Task):script(整体代码)、setTimeout、setInterval、I/O、事件、postMessage、 MessageChannel、setImmediate (Node.js)
    • 微任务 (Micro Task):Promise.then、 MutaionObserver、process.nextTick (Node.js)。
  • 宏任务每次只会执行第一个项目,所以这时会去看微任务列队。

Promise 是什么?有什么用途?

  • 回调函数是一个被当作参数传入、让另一个函数在未来某个时间点再调用的函数
  • Promise 是一个构造函式,我们需要透过 new 关键字建立一个 Promise。
fetch('https://explainthis.com/data')
  .then((response) => response.json())
  .then((data) =>{
    console.log(data);
  })
  .catch((error) =>{
    console.error(error);
  })
  .finally(() =>{
    console.log("close loader");
  });
  • async/await 是一种基于 Promise 之上的语法糖
async function getData() {
  const res = await fetch("https://getsomedata");
  const data = await res.json();
  console.log(data);
}
getData()

Promise.race 是什么?请实现 Promise.race

  • Promise.race接收一个内有多个 promises 的 Iterable ,例如 Array、Map、Set。回传最先 fulfill 或最先被 reject 的那一个
function promiseRace (promises) {
  for (const p of promises) {
    p.then((val) =>{
      resolve(val);
    }).catch((e) => {
      reject(e);
    })
  }
}

const slow = new Promise(r => setTimeout(() => r("slow"), 2000));
const fast = new Promise(r => setTimeout(() => r("fast"), 500));

promiseRace([slow, fast]).then(console.log);
// → "fast"

Promise.all 是什么?请实现 Promise.all

  • 接收一个可迭代对象(常见为数组)并行执行这些 Promise(不会按顺序等待)只有当 全部 Promise 都 fulfilled 时:→ 返回一个新的 Promise,值是一个数组→ 顺序与输入顺序一致,而不是完成顺序.如果 任何一个 promise 失败:→ Promise.all 立即 reject,不再等待其他任务
Promise.all([
  Promise.resolve(1),
  Promise.reject("oops"),
  Promise.resolve(3)
])
  .then(console.log)
  .catch(console.error);   // 输出: "oops"

JavaScript 中的 async/await 是什么?和 promise 有什么差别?

  • 语法: async/await 提供了更简洁、更直观的语法,使得异步代码更易读和维护。Promise 则需要使用 then 和 catch 方法来处理结果和错误,语法上较为冗长。
  • 错误处理: 在 async/await 中,可以直接使用 try…catch 来捕获错误,而在 Promise 中需要使用 catch 方法。
  • 代码流程: async/await 可以使异步代码看起来更像同步代码,更容易阅读和理解。Promise 的代码流程则较为不连贯。