JavaScript如何同步等待AJAX响应,不依赖回调按顺序获取服务端返回值
可实现同步等待AJAX响应的落地方案
尽管所有前端技术文档都明确标记同步网络请求存在阻塞主线程、冻结页面交互的弊端、不推荐生产环境使用,但从语法规则层面,完全可以实现你要求的代码执行效果,不存在需要特殊技巧的隐藏实现路径。
方案1:原生XMLHttpRequest同步模式(全场景兼容)
这是最基础的同步请求实现逻辑,不需要依赖第三方库,运行时不会额外触发jQuery兼容层的弃用警告:
function function_that_slowly_gets_city_name_from_server(zipCode) { const syncXhr = new XMLHttpRequest(); // open方法第三个参数传入false,代表开启同步阻塞模式,未拿到响应前不会执行后续代码 syncXhr.open('GET', `/api/lookup-city?zip=${zipCode}`, false); syncXhr.send(); // 直接同步返回服务端响应解析后的城市名 return JSON.parse(syncXhr.responseText).city; }
将该函数代入你提供的测试代码,即可完全复现预期的控制台输出顺序:
console.log('Before getting the city name.'); zip_code = '60601'; city_name = function_that_slowly_gets_city_name_from_server(zip_code); console.log(city_name); // 输出同步获取到的Chicago console.log('After getting the city name.');
方案2:jQuery环境下的兼容写法
哪怕官方将async: false标记为弃用状态,当前所有jQuery正式版本依然完整支持该参数的逻辑,写法和传统jQuery AJAX调用完全一致:
function function_that_slowly_gets_city_name_from_server(zipCode) { let cityName = ''; $.ajax({ url: `/api/lookup-city?zip=${zipCode}`, async: false, // 强制开启同步等待逻辑 success: (res) => { cityName = res.city; } }); return cityName; }
以上两种方案的运行逻辑完全一致:都会在请求返回前阻塞当前JS执行线程,直到服务端响应数据、请求超时或请求失败后才会继续执行后续代码。
实际使用的注意事项
- 同步请求的阻塞特性会导致请求未返回期间,所有页面交互(按钮点击、滚动、页面渲染更新)完全冻结,如果服务端响应延迟较长,用户会直接感知到页面卡死
- 现代浏览器会对主线程上的同步XHR请求输出控制台弃用警告,但不会直接拦截请求的正常执行
- 如果需要规避阻塞问题、同时不使用回调写法,只能通过
async/await拆分代码结构实现,但这种方式无法做到普通函数直接同步返回异步请求结果的效果,会改变你现有测试代码的执行顺序逻辑
内容的提问来源于stack exchange,提问作者David.Woosley
相关产品推荐
相关产品推荐

