龙空技术网

JavaScript中的间歇调用和超时调用

木森林林学苑 400

前言:

此时朋友们对“js间隔器”大约比较珍视,大家都需要剖析一些“js间隔器”的相关文章。那么小编同时在网络上网罗了一些有关“js间隔器””的相关知识,希望兄弟们能喜欢,姐妹们一起来学习一下吧!

JavaScript是单线程语言,但它允许通过设置超时值和间歇时间值来调度代码在特定的时刻执行。前者是在制定的时间过后执行代码,而后者则是每隔指定的时间就执行一次代码。

超时调用:setTimeout()方法

超时调用需要使用window对象的setTimeout()方法,它接收两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前需要等待多少毫秒)。其中,第一个参数可以是一个包含JavaScript代码的字符串(就和在eval()函数中使用的字符串一样),也可以是一个函数。但由于传递字符串可能导致性能损失,因此不建议以字符串作为第一个参数,如下:

// 不建议传递字符串setTimeout("console.log('hello world!')", 1000);// 推荐的调用方式setTimeout(function(){	console.log("hello world!");}, 1000);

第二个参数是一个表示等待多长时间的毫秒数,但经过该时间后,指定的代码不一定会执行。JavaScript是一个单线程序的解释器,因此一定时间内只能执行一段代码。为了控制要执行的代码,就有一个JavaScript任务队列。这些任务会按照它们添加到队列的顺序执行。setTimeout()的第二个参数告诉JavaScript再过多长时间把当前任务添加到队列中。如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么它就要等前面的代码执行完了以后再执行。

超时调用ID

调用setTimeout()之后,该方法会返回一个数值ID,表示超时调用。这个超时调用ID是计划执行代码的唯一标识符,可以通过它来取消超时调用。要取消尚未执行的超时调用计划,可以调用clearTimeout()方法并将相应的超时调用ID作为参数传递给它,如下:

// 设置超时调用var timeoutId = setTimeout(function(){	console.log('hello world!');}, 1000);// 把超时调用取消clearTimeout(timeoutId);

取消超时调用clearTimeout()

只要在指定的时间尚未过去之前调用clearTimeout(),就可以完全取消超时调用。前面的代码在设置超时调用之后马上又调用了cleatTimeout(),结果就跟什么也没有发生一样。

超时调用的代码都是在全局作用域中执行的,因此函数中this的值在非严格模式下指向window对象,在严格模式下是undefined。

间歇调用setInterval()

间歇调用与超时调用类似,只不过它会按照指定的时间间隔重复执行代码,直至间歇调用被取消或者页面被卸载。设置间歇调用的方法是setInterval(),它接受的参数与setTimeout()相同。如下:

// 不建议传递字符串setInterval("console.log('Hello World!')", 1000);// 推荐的调用方式setInterval(function(){	console.log('hello world!')}, 1000);

间歇调用ID和取消间歇调用clearInterval()方法

调用setInterval()方法同样也会返回一个间歇调用ID,该ID可用于在将来某个时刻取消间歇调用。要取消尚未执行的间歇调用,可以使用clearInterval()方法并传入相应的间歇调用ID。如下:

var num = 0;var max = 10;var intervalId = null;function incrementNumber(){	num++;	console.log(num);	if (num == max) {		clearTimeout(intervalId);		console.log("Done");	}}intervalId = setInterval(incrementNumber, 500);

使用超时调用来模拟间歇调用

这个模式也可以使用超时调用来实现,如下:

var num = 0;var max = 10;function incrementNumber(){	num++;	console.log(num);	if (num < max) {		setTimeout(incrementNumber, 500);	} else {		console.log("Done");	}}setTimeout(incrementNumber, 500);

可见,在使用超时调用时,没有必要跟踪超时调用ID,因为每次执行代码之后,如果不再设置另一次超时调用,调用就会自行停止。

一般认为,使用超时调用来模拟间歇调用是一种最佳模式。在开发环境下,很少使用真正的间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动。而像前面示例中那样使用超时调用,则完全可以避免这一点。所以,最好不要使用间歇调用。

PS:

1、在setTimeout中的业务会被阻塞到空闲时执行,而setInterval不会受其他业务的阻塞。

2、 js是单线程,但是js底层的引擎层是native代码,可以使用多线程。js的异步任务就是在引擎中通过线程池执行完成,然后通知js层。

标签: #js间隔器