事件循环 、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 的代码流程则较为不连贯。