为什么在高并发下很容易就被setInterval给坑了

 大多数程序员都被setInterval坑过吧,如果不是高并发,程序执行快,可能还不知道怎么回事。 

 模拟一个场景, 假如我们需要一个client.html ,每隔一秒,返回服务器sleep.php处理后的时间。

这个需求很简单,直接上代码吧。 client.html代码如下

<html>
<head>
<meta charset="utf-8">
</head>
<script src="//libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
<body>

<script type="text/javascript">
function test(){
	$.get('sleep.php',function(data){console.log(data);});
}
setInterval(test,1000);
</script>
</body>
</html>

服务端程序sleep.php如下

<?php
echo date('H:i:s');
?>

用浏览器打开 htpt://localhost/client.html ,并打开控制台,程序工作的很好,非常完美。

有一天程序特别受欢迎, 用户暴涨并发到了几百上千, sleep的程序也变得更复杂了,加入了一个复杂的业务比如计费系统,导致sleep.php 执行的时间非常长,模拟一下sleep.php 需要3秒。为了sleep.php 好看,老朱代码改成了下面的样子。

<?php
while(true){
   if(time()%3==0){
		echo date('H:i:s');
		exit;
   }
   sleep(1);
}

?>

这时候刷新http://localhost/client.html ,看控制台,神奇的事情发生了。间隔三秒输出,但是输出的时间变成了3个,看红色标注的部分。也就是客户端对服务器发起了3个并发连接,现实是sleep.php 执行的时间越长,client.html 间隔请求的时间越短,导致的并发越多(除非受限浏览器连接数) 。对于高并发,很可能就雪崩了。

那如何避免这种情况出现呢?怎么真正的实现每间隔一秒去服务器获取一次数据呢? 先看看interval和setTimeout的区别吧。

setInterval

setInterval()方法可按照指定的周期来调用函数或者计算表达式(以毫秒为单位)

语法:

setInterval(函数表达式,毫秒数);

setInterval()会不停的调用函数,直到clearInterval()被调用或者窗口被关闭,由 setInterval()返回的ID值可用作clearInterval()方法的参数。

setTimeout

setTimeout()方法用于在指定毫秒数后再调用函数或者计算表达式(以毫秒为单位)

语法:

setTimeout(函数表达式,毫秒数);

setTimeout()只执行函数一次,如果需要多次调用可以使用setInterval(),或者在函数体内再次调用setTimeout()

区别

  通过以上分析可以看出,setTimeout与setInterval的主要区别是:

  setTimeout()方法只运行一次,也就是说当达到设定的时间后就出发运行指定的代码,运行完后就结束了,如果还想再次执行同样的函数,可以在函数体内再次调用setTimeout(),可以达到循环调用的效果。

  setInterval()是循环执行的,即每达到指定的时间间隔就执行相应的函数或者表达式,是真正的定时器。

 

明白两个函数的区别,client.html这个程序稍微做一下改动就可以了。

<html>
<head>
<meta charset="utf-8">
</head>
<script src="//libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
<body>

<script type="text/javascript">
setTimeout(test,1000);
function test(){
	$.get('sleep.php',function(data){
		console.log(data);
        setTimeout(test,1000);
	});
}
</script>
</body>
</html>

再次刷新页面,并发消失,并且在服务器sleep.php执行完成后,再请求服务器的内容。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值