JavaScript-异步和同步函数使用场景及区别-正确构建程序的核心要点

文章目录

  • 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. queueMicrotaskprocess.nextTick(Node.js))
    • [7. Web APIs(如 `requestAnimationFrame`、`Geolocation` 等)](#7. Web APIs(如 requestAnimationFrameGeolocation 等))
    • [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.stringifyreviver / replacer 回调)
    • [6. `RegExp` 的 `exec` / `test` 回调(如果使用函数)](#6. RegExpexec / 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 请求

  • 使用 XMLHttpRequestfetch(结合 .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. queueMicrotaskprocess.nextTick(Node.js)

  • 微任务(Microtask)队列中的回调是异步的。
javascript 复制代码
queueMicrotask(() => console.log("Microtask callback"));
// Node.js 专属
process.nextTick(() => console.log("nextTick callback"));

7. Web APIs(如 requestAnimationFrameGeolocation 等)

  • 浏览器提供的 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 更推荐使用 Promiseasync/await 替代传统的回调嵌套(回调地狱)。

如果需要判断一个函数是否是异步执行的,可以检查它是否属于上述场景或依赖底层异步 API。

2.同步函数使用场景

在 JavaScript 中,大多数回调函数是同步执行的 ,但某些特定场景下(如 I/O、定时器、事件监听等)会是异步的。以下是常见的 同步回调函数 场景:

1. 数组迭代方法(Array Methods)

JavaScript 的数组方法(如 mapfilterforEachreducesomeevery 等)的回调函数是 同步执行 的:

javascript 复制代码
const arr = [1, 2, 3];
arr.map((item) => {
  console.log(item); // 同步执行
  return item * 2;
});
console.log("Done"); // 在所有 map 回调完成后执行

输出顺序

复制代码
1
2
3
Done

结论mapfilterforEach 等方法的回调是同步的。


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.definePropertyProxy 定义 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.stringifyreviver / replacer 回调

JSON.parsereviverJSON.stringifyreplacer 回调是 同步执行 的:

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. RegExpexec / test 回调(如果使用函数)

RegExpexectest 方法本身是同步的,但如果传入回调(如 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 回调是否同步
数组方法 mapfilterforEachreduce ✅ 同步
Promise 构造函数 new Promise(executor) ✅ 同步(但 .then 是异步)
对象访问器 Object.defineProperty / Proxyget/set ✅ 同步
Array.sort 比较函数 (a, b) => ... ✅ 同步
JSON 解析 JSON.parse(reviver) / JSON.stringify(replacer) ✅ 同步
String.replace 回调 (match) => ... ✅ 同步
Array.from mapFn 回调 ✅ 同步

同步异步区别

  • 同步回调:立即执行,阻塞后续代码。
  • 异步回调 :进入任务队列(如 setTimeoutfetchPromise.then、事件监听等)。

如果你需要判断某个回调是否同步,可以检查它是否属于上述同步场景,或者是否涉及 I/O、定时器、Promise 链等异步机制。

相关推荐
我命由我123451 小时前
35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)
java·服务器·开发语言·jvm·后端·架构·java-ee
&zzz1 小时前
Python生成exe
开发语言·python
Chandler241 小时前
Go:方法
开发语言·c++·golang
CopyLower2 小时前
分布式ID生成方案的深度解析与Java实现
java·开发语言·分布式
随便@_@3 小时前
基于MATLAB/simulink的信号调制仿真--AM调制
开发语言·matlab·simulink·移动仿真
爱代码的小黄人3 小时前
深入解析系统频率响应:通过MATLAB模拟积分器对信号的稳态响应
开发语言·算法·matlab
vsropy3 小时前
matlab安装python API 出现Invalid version: ‘R2022a‘,
开发语言·python
whoarethenext4 小时前
qt的基本使用
开发语言·c++·后端·qt
atec20004 小时前
使用uv管理python项目环境
开发语言·python·uv
清岚_lxn4 小时前
原生SSE实现AI智能问答+Vue3前端打字机流效果
前端·javascript·人工智能·vue·ai问答