一文吃透 JS 异步编程,从零基础到实战全详解
前言
JavaScript 是单线程语言,同一时间只能做一件事。如果所有代码都同步顺序执行,遇到网络请求、定时器、文件读取这类耗时操作,页面就会卡死阻塞,用户体验极差。异步编程就是为了解决单线程阻塞问题而生,是前端开发核心必备技能,也是面试高频考点。
本文从零讲解 JS 异步发展历程、核心原理、用法实战。
一、同步与异步核心区别
1. 同步执行
代码从上到下依次执行,上一行没执行完,下一行永远等待。
js
console.log("1");
console.log("2");
console.log("3");
输出顺序:1 → 2 → 3,顺序固定,依次执行。
2. 异步执行
耗时任务交给浏览器后台执行,主线程继续往下走,等任务完成再回头执行回调。
js
console.log("1");
setTimeout(() => {
console.log("2");
}, 1000);
console.log("3");
输出顺序:1 → 3 → 2定时器延时任务异步执行,不会阻塞主线程代码运行。
二、JS 异步发展四大阶段
阶段 1:回调函数(最原始异步)
原理
把耗时操作完成后要执行的代码,放进函数里当作参数传递,任务结束自动调用。
实战:定时器回调
js
// 延时2秒执行
setTimeout(function () {
console.log("异步任务执行完成");
}, 2000);
实战:模拟接口请求回调
js
// 模拟获取用户数据
function getUserInfo(callback) {
setTimeout(() => {
let user = { name: "前端小白", age: 22 };
callback(user); // 执行回调
}, 1500);
}
// 调用
getUserInfo((res) => {
console.log("拿到用户数据:", res);
});
缺点:回调地狱
多层异步嵌套,代码层层缩进,可读性极差、极难维护:
js
setTimeout(() => {
console.log("第一层");
setTimeout(() => {
console.log("第二层");
setTimeout(() => {
console.log("第三层");
}, 1000);
}, 1000);
}, 1000);
代码臃肿、无法统一捕获错误,正式项目禁止大量嵌套。
阶段 2:Promise(ES6 标准异步方案)
核心作用
解决回调地狱,把横向嵌套代码改成纵向链式调用,统一异步状态管理。
Promise 三种状态
- pending 进行中(初始状态)
- fulfilled 成功
- rejected 失败状态一旦改变,永久无法更改。
基础语法
js
// 创建Promise实例
let p = new Promise((resolve, reject) => {
// 异步耗时操作
let flag = true;
if (flag) {
resolve("请求成功数据"); // 成功调用
} else {
reject("请求失败"); // 失败调用
}
});
// 接收结果
p.then(res => {
console.log("成功:", res);
}).catch(err => {
console.log("失败:", err);
})
链式调用(解决回调地狱)
js
function fn1() {
return new Promise(resolve => {
setTimeout(() => resolve("第一步完成"), 1000);
});
}
function fn2() {
return new Promise(resolve => {
setTimeout(() => resolve("第二步完成"), 1000);
});
}
// 纵向流畅执行
fn1()
.then(res => {
console.log(res);
return fn2();
})
.then(res => {
console.log(res);
})
常用静态方法
1. Promise.all() 全部成功才成功,适合并发请求
js
let p1 = Promise.resolve("接口1");
let p2 = Promise.resolve("接口2");
Promise.all([p1, p2]).then(res => {
console.log("全部请求完成", res);
});
2. Promise.race () 竞速执行
规则:多个 Promise 同时执行,谁最先结束就返回谁的结果,其余任务继续执行但结果会被忽略。常用场景:接口请求超时拦截、竞速请求择优使用。
js
// 模拟两个不同耗时的异步任务
const task1 = new Promise((resolve) => {
setTimeout(() => resolve("任务1完成"), 2000);
});
const task2 = new Promise((resolve) => {
setTimeout(() => resolve("任务2完成"), 1000);
});
// 竞速执行
Promise.race([task1, task2])
.then(res => {
// 只会输出先完成的任务2
console.log("最先完成:", res);
})
实战超时请求案例(工作常用)
js
// 模拟接口请求
function requestData() {
return new Promise((resolve) => {
setTimeout(() => resolve("接口数据"), 3000);
})
}
// 超时限制
function timeOut() {
return new Promise((_, reject) => {
setTimeout(() => reject("请求超时,请重试"), 2000);
})
}
// 竞速:2秒内没请求成功直接判定超时
Promise.race([requestData(), timeOut()])
.then(res => console.log(res))
.catch(err => console.log(err))
Promise.allSettled()不管成功失败,统一获取所有结果Promise.resolve()快速创建成功 PromisePromise.reject()快速创建失败 Promise
阶段 3:async /await(ES7 优雅异步)
核心优势
以同步写法,实现异步逻辑,代码最简洁、可读性最高,企业项目主流用法。
使用规则
await只能放在 async 修饰的函数内部await后面必须跟 Promise 对象- 代码会暂停等待异步执行完毕,再往下走
基础实战
js
// 封装异步请求函数
function getMsg() {
return new Promise(resolve => {
setTimeout(() => {
resolve("后端返回数据");
}, 1500);
});
}
// async 声明异步函数
async function main() {
console.log("开始请求");
// 等待异步完成
let result = await getMsg();
console.log("拿到数据:", result);
console.log("后续逻辑执行");
}
// 调用
main();
异常捕获(必学)
异步请求大概率失败,用 try/catch 捕获错误:
js
async function getData() {
try {
let res = await getMsg();
console.log("成功", res);
} catch (err) {
console.log("请求出错:", err);
}
}
getData();
三、JS 异步底层核心:事件循环 EventLoop
通俗讲解
- JS 主线程执行同步代码,执行完清空执行栈
- 异步任务放入任务队列排队
- 同步代码全部执行完毕,再从队列取出异步任务执行
任务分类
- 微任务:优先级更高(Promise.then、async/await)
- 宏任务:优先级较低(setTimeout、ajax、DOM 事件)执行顺序:同步代码 → 所有微任务 → 所有宏任务
经典面试题小白版
js
console.log("同步1");
setTimeout(() => {
console.log("宏任务");
}, 0);
Promise.resolve().then(() => {
console.log("微任务");
});
console.log("同步2");
输出顺序:同步 1 → 同步 2 → 微任务 → 宏任务
四、实战场景总结
- 定时器延时操作:异步基础用法
- Ajax / Fetch / Axios 后端接口请求:全用 async+await
- 文件读写、图片预加载、页面异步渲染
- 多个接口按顺序先后请求
- 接口超时拦截:优先使用
Promise.race
五、学习路线总结
- 先懂同步异步概念,分清阻塞与非阻塞
- 掌握回调函数,理解异步底层逻辑
- 精通Promise 状态与所有静态方法
- 主力使用 async / await 写项目业务
- 吃透事件循环,搞定所有异步面试题
结尾寄语
JS 异步编程是前端从入门到进阶的分水岭,学会异步才算真正懂 JavaScript。摒弃老旧回调嵌套,熟练使用 Promise + async/await,既能写出优雅简洁代码,也能轻松应对求职面试,快速提升职场核心竞争力。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)