背景
上周有同事问我关于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('<br>');
let fail_result_msg = result.fail_data.map(item => item.msg).join('<br>');
console.log(success_result_msg, '>>>', fail_result_msg);
document.getElementById('success_results').innerHTML += success_result_msg + '<br>';
document.getElementById('fail_results').innerHTML += fail_result_msg + '<br>';
},
});
}
};
我的第一感觉,是不是浏览器将两次 dom 操作合并渲染了,所以让他在 success 最后加上
const clientWidth = document.body.clientWidth
这样能够让浏览器及时渲染一次以获得正确的 clientWidth
属性,但还是不能解决问题
后来同事给我找到一个链接 有ajax同步的方法里对页面的渲染能否起效?
解决问题
那应该就是 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('<br>');
let fail_result_msg = result.fail_data.map(item => item.msg).join('<br>');
console.log(success_result_msg, '>>>', fail_result_msg);
document.getElementById('success_results').innerHTML += success_result_msg + '<br>';
document.getElementById('fail_results').innerHTML += fail_result_msg + '<br>';
}
};