文章目录
- 1.异步函数使用场景
-
- [1. 定时器函数(Timers)](#1. 定时器函数(Timers))
- [2. 事件监听(Event Listeners)](#2. 事件监听(Event Listeners))
- [3. AJAX / HTTP 请求](#3. AJAX / HTTP 请求)
- [4. Node.js 异步 I/O 操作](#4. Node.js 异步 I/O 操作)
- [5. Promise 的 `then`/`catch`/`finally`](#5. Promise 的
then
/catch
/finally
) - [6. `queueMicrotask` 和 `process.nextTick`(Node.js)](#6.
queueMicrotask
和process.nextTick
(Node.js)) - [7. Web APIs(如 `requestAnimationFrame`、`Geolocation` 等)](#7. Web APIs(如
requestAnimationFrame
、Geolocation
等)) - [8. 异步函数(Async/Await)](#8. 异步函数(Async/Await))
- 总结
- 2.同步函数使用场景
-
- [1. 数组迭代方法(Array Methods)](#1. 数组迭代方法(Array Methods))
- [2. `Promise` 构造函数 & `new Promise` 的回调](#2.
Promise
构造函数 &new Promise
的回调) - [3. `Object.defineProperty` / `Proxy` 的访问器回调](#3.
Object.defineProperty
/Proxy
的访问器回调) - [4. `Array.sort` 的比较函数](#4.
Array.sort
的比较函数) - [5. `JSON.parse` / `JSON.stringify` 的 `reviver` / `replacer` 回调](#5.
JSON.parse
/JSON.stringify
的reviver
/replacer
回调) - [6. `RegExp` 的 `exec` / `test` 回调(如果使用函数)](#6.
RegExp
的exec
/test
回调(如果使用函数)) - [7. `Array.from` / `Array.of` 的回调(如果提供)](#7.
Array.from
/Array.of
的回调(如果提供)) - 总结:哪些回调是同步的?
- 同步异步区别
在 JavaScript 中,异步回调函数通常用于处理非阻塞操作,避免阻塞主线程的执行。以下是一些常见的使用异步回调函数的情况:
1.异步函数使用场景
1. 定时器函数(Timers)
setTimeout()
和setInterval()
的回调函数是异步的。
javascript
setTimeout(() => {
console.log("This runs after 1 second");
}, 1000);
2. 事件监听(Event Listeners)
- DOM 事件(如点击、键盘输入等)的回调函数是异步触发的。
javascript
button.addEventListener('click', () => {
console.log("Button clicked!");
});
3. AJAX / HTTP 请求
- 使用
XMLHttpRequest
或fetch
(结合.then()
)的回调是异步的。
javascript
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data)); // 异步回调
4. Node.js 异步 I/O 操作
- 文件读写、网络请求等操作的回调是异步的。
javascript
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data); // 异步回调
});
5. Promise 的 then
/catch
/finally
- Promise 的链式调用中的回调是异步的。
javascript
Promise.resolve().then(() => console.log("Async via Promise"));
6. queueMicrotask
和 process.nextTick
(Node.js)
- 微任务(Microtask)队列中的回调是异步的。
javascript
queueMicrotask(() => console.log("Microtask callback"));
// Node.js 专属
process.nextTick(() => console.log("nextTick callback"));
7. Web APIs(如 requestAnimationFrame
、Geolocation
等)
- 浏览器提供的 API 通常使用异步回调。
javascript
requestAnimationFrame(() => console.log("Animation frame callback"));
navigator.geolocation.getCurrentPosition((position) => {
console.log(position); // 异步回调
});
8. 异步函数(Async/Await)
async/await
是 Promise 的语法糖,本质仍是异步回调。
javascript
async function fetchData() {
const data = await someAsyncOperation(); // 等待异步操作
console.log(data); // 异步执行
}
总结
- 异步回调会在当前代码执行栈清空后(或满足条件时)执行,不会阻塞后续代码。
- 常见的异步场景包括:I/O 操作、网络请求、定时任务、事件驱动等。
- 现代 JavaScript 更推荐使用 Promise 或 async/await 替代传统的回调嵌套(回调地狱)。
如果需要判断一个函数是否是异步执行的,可以检查它是否属于上述场景或依赖底层异步 API。
2.同步函数使用场景
在 JavaScript 中,大多数回调函数是同步执行的 ,但某些特定场景下(如 I/O、定时器、事件监听等)会是异步的。以下是常见的 同步回调函数 场景:
1. 数组迭代方法(Array Methods)
JavaScript 的数组方法(如 map
、filter
、forEach
、reduce
、some
、every
等)的回调函数是 同步执行 的:
javascript
const arr = [1, 2, 3];
arr.map((item) => {
console.log(item); // 同步执行
return item * 2;
});
console.log("Done"); // 在所有 map 回调完成后执行
输出顺序:
1
2
3
Done
结论 :map
、filter
、forEach
等方法的回调是同步的。
2. Promise
构造函数 & new Promise
的回调
new Promise(executor)
的 executor
函数是 同步执行 的:
javascript
console.log("Start");
new Promise((resolve) => {
console.log("Inside Promise"); // 同步执行
resolve("Resolved");
}).then((result) => {
console.log(result); // 异步执行(微任务)
});
console.log("End");
输出顺序:
Start
Inside Promise
End
Resolved
结论 :Promise
构造函数的回调是同步的,但 .then()
/ .catch()
是异步的(微任务)。
3. Object.defineProperty
/ Proxy
的访问器回调
当使用 Object.defineProperty
或 Proxy
定义 get
/set
时,它们的回调是 同步执行 的:
javascript
const obj = {};
Object.defineProperty(obj, "name", {
get() {
console.log("Getter called"); // 同步执行
return "Alice";
},
});
console.log(obj.name); // 触发 getter
console.log("Done");
输出顺序:
Getter called
Alice
Done
结论 :属性访问器(get
/set
)的回调是同步的。
4. Array.sort
的比较函数
Array.sort
的比较函数(compareFunction
)是 同步执行 的:
javascript
const arr = [3, 1, 2];
arr.sort((a, b) => {
console.log(`Comparing ${a} and ${b}`); // 同步执行
return a - b;
});
console.log("Sorted:", arr);
输出顺序:
Comparing 1 and 3
Comparing 2 and 1
Comparing 2 and 3
Sorted: [1, 2, 3]
结论 :sort
的比较函数是同步的。
5. JSON.parse
/ JSON.stringify
的 reviver
/ replacer
回调
JSON.parse
的 reviver
和 JSON.stringify
的 replacer
回调是 同步执行 的:
javascript
const jsonStr = '{"name": "Alice", "age": 25}';
const obj = JSON.parse(jsonStr, (key, value) => {
console.log(`Parsing ${key}: ${value}`); // 同步执行
return value;
});
console.log("Done");
输出顺序:
Parsing name: Alice
Parsing age: 25
Parsing : [object Object]
Done
结论 :JSON
解析/序列化的回调是同步的。
6. RegExp
的 exec
/ test
回调(如果使用函数)
RegExp
的 exec
或 test
方法本身是同步的,但如果传入回调(如 String.replace
的函数参数),它也是同步执行:
javascript
const str = "Hello World";
str.replace(/World/, (match) => {
console.log(`Matched: ${match}`); // 同步执行
return "JS";
});
console.log("Done");
输出顺序:
Matched: World
Done
结论 :String.replace
的回调是同步的。
7. Array.from
/ Array.of
的回调(如果提供)
Array.from
可以接收一个 mapFn
回调,它是 同步执行 的:
javascript
const arr = Array.from([1, 2, 3], (x) => {
console.log(`Processing ${x}`); // 同步执行
return x * 2;
});
console.log("Done");
输出顺序:
Processing 1
Processing 2
Processing 3
Done
结论 :Array.from
的回调是同步的。
总结:哪些回调是同步的?
场景 | 方法/API | 回调是否同步 |
---|---|---|
数组方法 | map 、filter 、forEach 、reduce |
✅ 同步 |
Promise 构造函数 |
new Promise(executor) |
✅ 同步(但 .then 是异步) |
对象访问器 | Object.defineProperty / Proxy 的 get /set |
✅ 同步 |
Array.sort |
比较函数 (a, b) => ... |
✅ 同步 |
JSON 解析 |
JSON.parse(reviver) / JSON.stringify(replacer) |
✅ 同步 |
String.replace |
回调 (match) => ... |
✅ 同步 |
Array.from |
mapFn 回调 |
✅ 同步 |
同步异步区别
- 同步回调:立即执行,阻塞后续代码。
- 异步回调 :进入任务队列(如
setTimeout
、fetch
、Promise.then
、事件监听等)。
如果你需要判断某个回调是否同步,可以检查它是否属于上述同步场景,或者是否涉及 I/O、定时器、Promise 链等异步机制。