有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。
这里有一个使用同步XMLHttpRequest的简单解决方案:
function sleep(n){
var request = new XMLHttpRequest();
request.open('GET', '/sleep.php?n=' + n, false); // `false` makes the request synchronous
request.send(null);
}
sleep.php文件的内容:
<?php sleep($_GET['n']);
现在用以下方式调用它:
sleep(5);
使用现有服务器实现
如果您没有自己的应用程序服务器(对于上面的PHP脚本),可以使用一些在线服务。例如:
函数睡眠(n){var request=new XMLHttpRequest();request.open('GET','http://httpstat.us/200?sleep='+n,假);request.send(空);};睡眠(1000);console.log(“一秒延迟完成”);
支持
关于为异步参数传递false,mdn注意到:
主线程上的同步请求很容易破坏用户体验,应该避免;事实上,许多浏览器已完全弃用主线程上的同步XHR支持。Workers中允许同步请求。
实际延迟时间
作为参数传递的毫秒数将是服务器在接收请求和发送响应之间等待的时间。传输和服务器负载所引起的延迟将被添加到其中。
需要使用“休眠”方法的对象的方法,如下所示:
function SomeObject() {
this.SomeProperty = "xxx";
return this;
}
SomeObject.prototype.SomeMethod = function () {
this.DoSomething1(arg1);
sleep(500);
this.DoSomething2(arg1);
}
几乎可以翻译为:
function SomeObject() {
this.SomeProperty = "xxx";
return this;
}
SomeObject.prototype.SomeMethod = function (arg1) {
var self = this;
self.DoSomething1(arg1);
setTimeout(function () {
self.DoSomething2(arg1);
}, 500);
}
不同之处在于,“SomeMethod”操作在执行操作“DoSomething2”之前返回。“SomeMethod”的调用者不能依赖于此。由于“睡眠”方法不存在,我使用后一种方法并相应地设计代码。
如果你写一个这样的睡眠函数
var sleep = function(period, decision, callback){
var interval = setInterval(function(){
if (decision()) {
interval = clearInterval(interval);
callback();
}
}, period);
}
你有一个异步函数可以多次调用,
var xhr = function(url, callback){
// Make an Ajax request
// Call a callback when the request fulfils
}
您的项目设置如下:
var ready = false;
function xhr1(){
xhr(url1, function(){ ready = true;});
}
function xhr2(){
xhr(url2, function(){ ready = true; });
}
function xhr3(){
xhr(url3, function(){ ready = true; });
}
然后您可以执行以下操作:
xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
// Do more
});
而不是像这样无休止的回调缩进:
xhr(url1, function(){
xhr2(url2, function(){
xhr3(url3, function(){
// Do more
});
});
});
我会将setTimeOut封装在Promise中,以实现与其他异步任务的代码一致性:Fiddle中的Demo
function sleep(ms)
{
return(new Promise(function(resolve, reject) {
setTimeout(function() { resolve(); }, ms);
}));
}
它的用法如下:
sleep(2000).then(function() {
// Do something
});
如果您习惯使用Promise,那么很容易记住语法。
在JavaScript中,我重写了每个函数,以便它能够尽快结束。您希望浏览器恢复控制,以便它可以更改DOM。
每次我想在函数中间休眠时,我都会重构以使用setTimeout()。
Edit
任何语言中臭名昭著的睡眠或延迟功能都备受争议。有些人会说,应该总是有一个信号或回调来启动给定的功能,而另一些人会认为,有时任意的延迟时间是有用的。我说,每个人都有自己的规则,在这个行业中,一条规则永远无法支配任何事情。
编写睡眠函数很简单,而且使用JavaScript Promises更容易使用:
// sleep time expects milliseconds
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
// Usage!
sleep(500).then(() => {
// Do something after the sleep!
});