实际开发中遇到的问题,当从后台获取到省份和城市,并赋值给页面表单中,但是代码中已经设置了根据省份变化清空页面城市信息。这就会产生一个问题,就是填写表单时,你的省份和城市都是空,当获取到后台数据并赋值到前台,前台监听到省份发生了变化,城市表单控件内容就会被清空。如何解决这一类问题?思路:js是单线程执行,当执行完清空后,再将后台城市数据赋值到前台。
function handle(){
var good_key = $('#good_key'); // 商品主键
var good_name = $('#good_name'); // 商品名称
if (good_key.val() === ""){
good_name.val("");
return;
}
if (valid(good_key.val()) == false){ //校验不通过
good_key.val(""); // 假使:当这个值发生变化紧接着触发change事件
good_name.val("");
return;
}
// 其他通过查询sql获取good_name的值
......
}
$('#good_key').on("change",handle,false); //监听good_key元素值的变化
观察上面事项,如果 good_key的值输入校验不对,会触发两次change事件,处理方式为同步,而我们需要当执行完第一次change事件完成后再去执行第二次change事件,进行异步处理。
首先,JavaScript是单线程执行的,也就是无法同时执行多段代码,当某一段代码正在执行的时候,所有后续的任务都必须等待,形成一个队列,一旦当前任务执行完毕,再从队列中取出下一个任务。这也常被称为“阻塞式执行”。所以一次鼠标点击,或是计时器到达时间点,或是Ajax请求完成触发了回调函数,这些事件处理程序或回调函数都不会立即运行,而是立即排队,一旦线程有空闲就执行。假如当前JavaScript进程正在执行一段很耗时的代码,此时发生了一次鼠标点击,那么事件处理程序就被阻塞,用户 也无法立即看到反馈,事件处理程序会被放入任务队列,直到前面的代码结束以后才会被开始执行。如果代码中设定一个setTimeout,那么浏览器便会在合适的时间,将代码插入任务队列,如果这个时间设定为0,就代表立即插入队列,但不是立即执行,仍然要等待前面代码执行完毕。所以setTimeout并不能保证执行的时间,是否即使执行取决于JavaScript线程是拥挤还是空闲。
举个例子:
function aa(){
var obj ={name:"",age:0,sex:''};
setTimeout(function(){
obj.name="王";
console.log(obj);
},0);
console.log(obj);
}
输出结果:
这样就可以使用setTimeout(fn,0)起到一个将事件加入到队列中,待执行的一个功能效果。