欢迎光临杨雨的个人博客站!

杨雨个人网站-杨雨个人博客-杨照佳

杨雨个人博客网站

关注互联网和搜索引擎的个人博客网站

首页 > WEB开发 > JavaScript >

javascript按时器事变道理

发布时间:2016-11-23  编辑:杨雨个人博客网站   点击:   

  说到 javascript 中的按时器,我们必定会想到 setTimeout() 和 setInterval() 这两个函数。本文将从 变乱轮回(Event Loop) 的角度来说明两者的事变道理和区别。

 setTimeout()

  MDN对 setTimeout 的界说为:

在指定的耽误时刻之后挪用一个函数或执行一个代码片断。

  语法

  setTimeout 的语法很是简朴,第一个参数为回调函数,第二个参数为延时的时刻。函数返回一个数值范例的ID独一标示符,此ID可以用作 clearTimeout 的参数来打消按时器:

var timeoutID = window.setTimeout(code, delay);

  IE0+ 还支持回调参数的传入:

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

 setInterval()

  MDN 对 setInterval 的界说为:

周期性地挪用一个函数(function)可能执行一段代码。

  因为 setInterval 和 setTimeout 的用法一样,以是这里不再列出。

 对第二个参数(delay)的声名

  因为javascript 的变乱轮回机制,导致第二个参数并不代表耽误delay毫秒之后当即执行回调函数,而是实行将回调函数插手到变乱行列。现实上,setTimeout 和 setInterval 在这一点上处理赏罚又存在区别:

  • setTimeout:延时delay毫秒之后,啥也不管,直接将回调函数插手变乱行列。
  • setInterval: 延时delay毫秒之后,先看看变乱行列中是否存在还没有执行的回调函数(setInterval的回调函数),假如存在,就不要再旧变乱行列里插手回调函数了。

  以是,当我们的代码中存在耗时的使命时,按时器并不会示意的如我们所想的那样。

 通过一个例子来领略

  下面的代码,原来但愿可以或许在 100ms 和 200ms 的时辰(也就是恰恰守候 100ms)挪用回调函数:

var timerStart1 = now();
setTimeout(function () {
  console.log('第一个setTimeout回调执行守候时刻:', now() - timerStart1);

  var timerStart2 = now();
  setTimeout(function () {
    console.log('第二个setTimeout回调执行守候时刻:', now() - timerStart2);
  }, 100);
}, 100);
// 输出:
// 第一个setTimeout回调执行守候时刻: 106
// 第二个setTimeout回调执行守候时刻: 107

  这样的功效看上去正是我们所想的那样,可是一旦我们在代码中插手了耗时的使命时辰,功效就不像我们所祈望的那样了:

var timerStart1 = now();
setTimeout(function () {
  console.log('第一个setTimeout回调执行守候时刻:', now() - timerStart1);

  var timerStart2 = now();
  setTimeout(function () {
    console.log('第二个setTimeout回调执行守候时刻:', now() - timerStart2);
  }, 100);

  heavyTask();  // 耗时使命
}, 100);

var loopStart = now();
heavyTask(); // 耗时使命
console.log('heavyTask淹灭时刻:', now() - loopStart);

function heavyTask() {
  var s = now();
  while(now() - s < 1000) {
  }
}

function now () {
  return new Date();
}
// 输出:
// heavyTask淹灭时刻: 1015
// 第一个setTimeout回调执行守候时刻: 1018
// 第二个setTimeout回调执行守候时刻: 1000

  两个 setTimeout 的守候变乱因为耗时使命的存在不再是 100ms 了!我们来描写一下工作的颠末:

  1. 起首,第一个耗时使命(heavyTask())开始执行,它必要约莫 1000ms 才气执行完毕。
  2. 从耗时使命开始执行,过了 100ms, 第一个 setTimeout 的回调函数祈望执行,于是被插手到变乱行列,可是此时前面的耗时使命还没执行完,以是它只能在行列中守候,直到耗时使命执行完毕它才开始执行,以是功效中我们开的看到的是: 第一个setTimeout回调执行守候时刻: 1018。
  3. 第一个 setTimeout 回调一执行,又开启了第二个 setTimeout, 这个按时器也是祈望延时 100ms 之后可以或许执行它的回调函数。 可是,在第一个 setTimeout 又存在一个耗时使命,全部它的剧情跟第一个按时器一样,也守候了 1000ms 才开始执行。

  可以用下面的图来归纳综合:

setTimeout

  再来看 setInterval 的一个例子:

var intervalStart = now();
setInterval(function () {
  console.log('interval距界说按时器的时刻:', now() - loopStart);
}, 100);

var loopStart = now();
heavyTask();
console.log('heavyTask淹灭时刻:', now() - loopStart);

function heavyTask() {
  var s = now();
  while(now() - s < 1000) {
  }
}

function now () {
  return new Date();
}
// 输出:
// heavyTask淹灭时刻: 1013
// interval距界说按时器的时刻: 1016
// interval距界说按时器的时刻: 1123
// interval距界说按时器的时刻: 1224

  上面这段代码,我们祈望每隔 100ms 就打出一条日记。相对付 setTimeout 的区别, setInterval 在筹备把回调函数插手到变乱行列的时辰,会判定行列中是否尚有未执行的回调,假若有的话,它就不会再往行列中添加回调函数。 否则,会呈现多个回调同时执行的环境。

  可以用下面的图来归纳综合:

setInterval

 总结

  上面临javascript按时器执行道理举办了扼要的说明,但愿可以或许辅佐我们更深入的领略javascript。文中有描写不妥的处所可以在评述中指出。

本文地址:http://itbyc.com/web/javascript/13031.html
转载请注明出处。
分享是一种快乐,也是一种美德:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
博客首页 | WEB开发 | 网站运营 | CMS使用教程 滇ICP备14002061号-1