JavaScript能否同时执行两个异步函数或回调?还是需等待前一个执行完毕再执行下一个?
咱们先把核心原理说透:JavaScript是单线程的——这意味着它同一时间只能执行一段代码逻辑。但别误会,异步操作本身(比如网络请求、文件读取、I/O处理)是由宿主环境(浏览器或者Node.js)的其他线程来处理的,JS只负责在这些操作完成后,执行对应的回调函数。
接下来咱们逐个拆解你提到的场景:
场景1:同时发起两个fetch请求
看你这段代码:
async function handleResponse1 () {/* some code */} async function handleResponse2 () {/* some code */} fetch('https://github.com').then(handleResponse1); fetch('https://stackoverflow.com').then(handleResponse2);
两个fetch请求确实会同时发起——因为浏览器有专门的网络线程池来处理这些请求,它们互不干扰。但当响应回来后,handleResponse1和handleResponse2并不会同时执行:这两个回调会被加入到JS的事件队列里,等主线程当前的任务都处理完了,再按顺序依次执行(谁的响应先回来,谁的回调就先被加入队列,先执行)。
哪怕两个响应同时到达,JS也只能先把其中一个回调执行完,再去执行另一个——毕竟单线程嘛。
场景2:Express同时收到三个端点请求
再看这段Express的代码:
async function getUsers () {/* some code*/} async function getCourses () {/* some code*/} async function getProducts () {/* some code*/} app.get('/users', getUsers); app.get('/courses', getCourses); app.get('/products', getProducts);
当三个请求同时打过来时,Node.js的底层会先接收这些请求,然后把对应的getUsers、getCourses、getProducts回调加入事件队列。JS主线程会挨个从队列里取出这些回调执行,不会同时运行这三个函数。
不过因为这三个函数都是async的,如果函数内部有await(比如等待数据库查询结果),主线程会暂时挂起当前函数,去处理队列里的下一个回调——这会给人一种"同时处理"的感觉,但本质是并发执行(交替切换任务),不是真正的并行(同时跑多个函数)。
场景3:Node.js读文件时收到Express请求
最后这个场景的代码:
async function processFileData () {/*some code*/} async function processRequestData () {/*some code*/} fs.readFile('/test.txt', 'utf8' , processFileData) app.get('/some-endpoint', processRequestData);
fs.readFile是Node.js的异步I/O操作,由libuv的线程池处理,和Express的请求处理互不影响。当文件读取完成、同时Express请求到达时,两个回调processFileData和processRequestData会被加入事件队列。同样,JS主线程会按队列顺序(谁先完成谁先排)依次执行,不会同时运行这两个函数。
总结一下
- 异步操作的发起可以"同时"进行(靠宿主环境的其他线程)
- 但回调函数的执行是单线程的,同一时间只能跑一个,按事件队列的顺序来
- async/await只是让异步代码写起来像同步代码,本质还是利用事件循环实现并发,不是真正的并行
内容的提问来源于stack exchange,提问作者Amjed Omar

