为什么JavaScript中for循环内请求未完成就执行后续代码?
执行顺序异常的原因
- 参数配置错误导致异步属性未生效:jQuery的
$.get()方法的标准传参顺序为(url, [请求数据], [成功回调], [返回数据类型]),你将async=false写在第二个参数位置的写法完全无效,所有请求依然是默认的异步执行模式。 - JavaScript的异步任务执行机制决定:异步请求的回调函数会被放入事件队列,必须等主线程的所有同步代码执行完毕后才会被调用。你写的for循环只是触发了所有请求的发送,主线程不会等待请求返回,会立刻执行循环后的更新DOM、打印日志的同步代码,等请求响应回来后才会执行
then中的合并逻辑,因此出现了你看到的执行顺序。 - 额外说明:就算你用正确的配置开启同步请求,也会阻塞整个浏览器主线程,导致用户无法操作页面,属于已经被官方废弃的不推荐用法,生产环境禁止使用。
修复方案
你可以通过$.when监听所有异步请求的完成状态,等所有请求返回、数据合并完成后再执行后续的更新逻辑,修复后的代码如下:
console.log('First Script'); const html = JSON.parse(document.getElementById('json').innerHTML); const associatedFiles = html.associatedFiles; if (typeof associatedFiles === 'undefined') { console.log('No files to compile'); } else { console.log('associatedFiles Found'); // 收集所有请求的Promise实例 const requestArr = Object.values(associatedFiles).map(fileUrl => { return $.get(fileUrl).then(data => { $.merge(html.data, data.data); console.log('html.data.length:', html.data.length); }) }) // 等待所有请求全部执行完成 $.when(...requestArr).then(() => { $("#json").html(JSON.stringify(html)); console.log('associatedFiles Compiled'); console.log($("#json").html()); }) }
内容的提问来源于stack exchange,提问作者warrentyy
相关产品推荐
相关产品推荐

