背景
上周有同事问我关于ajax的问题(同事是测试,他自己写的js脚本),在一个循环中使用 jquery 的 $.ajax 方法获取数据后更新 dom,但出现的问题是更新 dom 会在循环请求完成后再渲染。
分析问题
这是同事发给我的代码(省略了部分数据)
document.getElementById('send').onclick = function() { // ... for (var group = 1; group <= groupsNums + 1; group++) { // ... $.ajax({ async: false, url: '/invest', type: 'POST', // timeout: 6000, contentType: 'application/x-www-form-urlencoded', data: { csrfmiddlewaretoken: token, definedEnv: definedEnv, env: env, nums: nums, phone: phone, passwd: passwd, prodcutList: prodcutList, minAmount: minAmount, maxAmount: maxAmount, multiple: multiple, group: group, }, dataType: 'json', success: function(result) { // var data=JSON.parse(result); console.log(result, '>>>', typeof result); // console.log($('#results').html) console.log('bbb:', result.code); // $('#results').innerHTML = JSON.stringify(result) let success_result_msg = result.succss_data.map(item => item.msg).join(''); let fail_result_msg = result.fail_data.map(item => item.msg).join(''); console.log(success_result_msg, '>>>', fail_result_msg); document.getElementById('success_results').innerHTML += success_result_msg + ''; document.getElementById('fail_results').innerHTML += fail_result_msg + ''; }, }); }};复制代码
我的第一感觉,是不是浏览器将两次 dom 操作合并渲染了,所以让他在 success 最后加上
const clientWidth = document.body.clientWidth
这样能够让浏览器及时渲染一次以获得正确的 clientWidth
属性,但还是不能解决问题
后来同事给我找到一个链接
解决问题
那应该就是 async: false
导致的问题了,为了保证渲染顺序不出错,我们可以改写成 async await 的方式,在保证异步加载同步控制的同时不会阻塞主进程
document.getElementById('send').onclick = async function() { // ... for (var group = 1; group <= groupsNums + 1; group++) { // ... const result = await $.ajax({ url: '/invest', type: 'POST', // timeout: 6000, contentType: 'application/x-www-form-urlencoded', data: { csrfmiddlewaretoken: token, definedEnv: definedEnv, env: env, nums: nums, phone: phone, passwd: passwd, prodcutList: prodcutList, minAmount: minAmount, maxAmount: maxAmount, multiple: multiple, group: group, }, dataType: 'json', }); // var data=JSON.parse(result); console.log(result, '>>>', typeof result); // console.log($('#results').html) console.log('bbb:', result.code); // $('#results').innerHTML = JSON.stringify(result) let success_result_msg = result.succss_data.map(item => item.msg).join(''); let fail_result_msg = result.fail_data.map(item => item.msg).join(''); console.log(success_result_msg, '>>>', fail_result_msg); document.getElementById('success_results').innerHTML += success_result_msg + ''; document.getElementById('fail_results').innerHTML += fail_result_msg + ''; }};复制代码
作者其他文章:
github: