定时器
什么是定时器?
定时器是一种系统事件,由运行环境实现和触发。
通过定时器,开发者可以不依赖于用户的操作而自动调用执行某些代码
js中支持两种定时器事件:一次性事件、循环事件
定时器示例
// http://www.runoob.com/try/try.php?filename=tryjsref_win_settimeout1
<button onclick="myFunction()">点我</button>
<script>
var myVar;
function myFunction() {
myVar = setTimeout(alertFunc, 3000);
// 此处如果添加更多代码,则输出结果将可能不确定
console.log("hello from console");
}
function alertFunc() {
alert("Hello from window");
}
</script>
输出结果是: "hello from console" "hello from window"
异步执行
- 代码顺序:在代码中的前后顺序,反映了编辑时的两段代码之间的顺序。
- 执行顺序:在运行时的顺序。对于支持异步执行的系统,执行顺序是不确定的。
js定时器允许函数引用作为它的参数,使得函数的声明和执行分离为两个阶段。
- setTimeout(alertFunc, 3000)本身是函数声明和执行为一体的,它与后面的console.log("hello from console")是同步关系
- alertFunc则分为声明和调用两个部分。其中调用过程是隐式的, 它由系统来执行,调用时点则取决于定时器函数的设置。
也就是说alertFunc()的执行顺序与它所在的代码顺序无关,称之为异步执行。
被阻塞的定时器
// http://www.runoob.com/try/try.php?filename=tryjsref_win_settimeout1
<button onclick="myFunction()">点我</button>
<script>
function myFunction() {
setTimeout(consoleFunc, 3000);
setTimeout(alertFunc, 3000);
alert("我是窗口主线程");
}
function alertFunc() { alert("Hello from window");}
function consoleFunc() {console.log("hello from console");}
</script>
- 当"我是窗口主线程"的对话框未被用户点击OK按钮之前,两个定时器均不会被执行(被阻塞),即使定时时间已超时。
- 假如用户先等足3秒之后,再点击对话框的OK按钮, 则两个定时器处理函数会立即被执行,似乎这些定时器已排队到位,但等待前面的代码被执行完毕。
- 进一步观察发现:
alert
这一类涉及操作系统子窗口的函数被执行时,浏览器主窗口将无法接收用户的输入,其代码也停止执行;故这类包含窗口函数的代码是典型的阻塞式操作。也因此应当避免使用alert这类功能
异步执行:不确定的运行时顺序
setTimeout(function(){console.log('1')}, 3000);
for(i=0;i<10000;i++) {doSomething()} ;
console.log('2')
上述结果是12还是21,取决于浏览器所在机器执行循环的实际时间
如果你希望确保输出的是12,该如何做? 在后续的ajax中,我们将再次讨论异步
同步与异步、串行与并行这两组词之间的区别?