当前位置:嗨网首页>书籍在线阅读

03-回调

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

14.2 回调

回调是JavaScript中最古老的异步方式,其实我们已经在处理用户输入和超时中见过它的用法了。简单来说回调就是写一个函数,然后在未来的某个时刻调用它。这个函数本身并没有什么特别之处:它只是一个一般的JavaScript的函数。通常,会把这些回调函数提供给别的函数,或者将它们设为对象属性(又或者,在数组中使用它们,这种情况极少)。一般来说(并非总是如此),回调都是匿名函数。

从一个简单的例子开始,使用 setTimeout ,这是JavaScript的内建函数,可以将函数的执行推迟指定的毫秒数:

console.log("Before timeout: " + new Date());
function f() {
   console.log("After timeout: " + new Date());
}
setTimeout(f, 60*1000); // 1分钟
console.log("I happen after setTimeout!");
console.log("Me too!");

在控制台运行这些代码,如果打字速度不是特别慢,大家会看到类似下面的输出:

Before timeout: Sun Aug 02 2015 17:11:32 GMT-0700 (Pacific Daylight Time)
I happen after setTimeout!
Me too!
After timeout: Sun Aug 02 2015 17:12:32 GMT-0700 (Pacific Daylight Time)

这里,代码编写的顺序与实际执行的顺序之间没有必然联系,这通常是初学者纠结的地方。有些人会觉得,甚至期望,计算机执行代码的顺序跟我们编写代码的顺序是一样的。也就是说,希望看到如下输出:

Before timeout: Sun Aug 02 2015 17:11:32 GMT-0700 (Pacific Daylight Time)
After timeout: Sun Aug 02 2015 17:12:32 GMT-0700 (Pacific Daylight Time)
I happen after setTimeout!
Me too!

这可能才是大家想看到的结果,但它却不是异步。异步执行的主旨在于,它不会阻塞任何事。由于JavaScript是单线程的,如果告诉程序在执行某些代码之前等待60秒,而此时立刻执行这段代码的话,就什么都不会发生。程序将会暂停:它不会接收用户数据,更不会做刷新屏幕等事情。大家可能都经历过类似的事情,那绝不是令人满意的结果。异步技术可以帮助避免这种“锁定”发生。

在本例中,为了解释得更清楚,作者给 setTimeout 传入一个有名字的函数。一般情况下,除非因为编译问题从而不得不给函数命名,通常都会用匿名函数:

setTimeout(function() {
   console.log("After timeout: " + new Date());
}, 60*1000); 

setTimeout 在使用上有一个小问题:因为数字类型的超时参数在最后,当它跟特别长的匿名函数一起作为参数时,这个参数很容易漏掉,或者被看做是匿名函数的一部分。这很容易出错,不过,要习惯于将 setTimeout 和匿名函数一起使用。只要记住最后一行需要包含一个超时参数即可。