setTimeout(func,0)第二个参数为0分析

2018-8-20 00:30| 作者: admin| 查看: 419| 评论: 0|来自: 蚂蚁部落

在很多实际项目中,会有如下类似代码:

[JavaScript] 纯文本查看 复制代码
setTimeout(func,0)

看上去比较怪异,为何要等着0秒以后再去执行func函数,而不是直接调用。

可能不少初学者和当年本人一样,甚至会生出这样的想法,是不是项目人员在装逼或者故弄玄虚。

出现上述想法,基本是因为对于如下两个方法和概念没有理解透彻:

(1).setTimeout()方法一章节。

(2).JavaScript异步详解一章节。

首先看一段代码实例:

[JavaScript] 纯文本查看 复制代码运行代码
for (var index = 1; index <= 3; index++) {
  setTimeout(function(){
    console.log(index);
  },0);  
};

在直观上,打印结果应该是1,2,3,但是实际打印结果是4,4,4

结果分析如下:

即便第二个参数为0,setTimeout方法依然具有异步功能,又由于JavaScript是单线程,所以setTimeout回调函数只能在队列中排队,等待for循环执行完毕,这时index值已经变成4,所以打印结果都是4。

再来看一段实例代码加深与上述代码的理解:

[JavaScript] 纯文本查看 复制代码
function onReady(fn) {
  var readyState = document.readyState;
  if (readyState ==="interactive" || readyState === "complete") {
    fn();
  } else {
    window.addEventListener("DOMContentLoaded", fn);
  }
}
onReady(function () {
  console.log("DOM结构加载完毕");
});
console.log("开始输出:");

上述代码本意要实现,当文档结构完全加载完毕再去执行onReady的回调函数。

但是代码有一个问题,代码会根据DOM加载的状态,输出结果也会不同。

如果DOM结构未加载完毕,以异步的方式执行fn,如果DOM结构已经加载完毕,以同步的方式执行fn。

加载完毕输出顺序:

(1)."DOM结构加载完毕"。

(2)."开始输出"。

未加载完毕输出顺序:

(1)."开始输出"。

(2)."DOM结构加载完毕"。

所以要防止上面问题的出现,统一做异步处理,代码实例如下:

[JavaScript] 纯文本查看 复制代码
function onReady(fn) {
  var readyState = document.readyState;
  if (readyState ==="interactive" || readyState === "complete") {
    setTimeout(fn, 0);
  } else {
    window.addEventListener("DOMContentLoaded", fn);
  }
}
onReady(function () {
  console.log("DOM结构加载完毕");
});
console.log("开始输出:");

上面代码通过setTimeout(fn, 0)方式巧妙解决所存在的问题。


鲜花

握手

雷人

路过

鸡蛋

最新评论

返回顶部