有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。
我也遇到过类似的问题,必须等待控件的存在并每隔一段时间进行检查。由于JavaScript中没有真正的休眠、等待或暂停,并且Internet Explorer中不正确支持使用wait/async,因此我使用setTimeOut并注入函数以成功找到元素。以下是完整的示例代码,因此每个人都可以复制并将其用于自己的项目:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
var ElementSearchStatus = {
None: 0,
Found: 1,
NotFound: 2,
Timeout: 3
};
var maxTimeout = 5;
var timeoutMiliseconds = 1000;
function waitForElement(elementId, count, timeout, onSuccessFunction) {
++count;
var elementSearchStatus = existsElement(elementId, count, timeout);
if (elementSearchStatus == ElementSearchStatus.None) {
window.setTimeout(waitForElement, timeoutMiliseconds, elementId, count, timeout, onSuccessFunction);
}
else {
if (elementSearchStatus == ElementSearchStatus.Found) {
onSuccessFunction();
}
}
}
function existsElement(elementId, count, timeout) {
var foundElements = $("#" + elementId);
if (foundElements.length > 0 || count > timeout) {
if (foundElements.length > 0) {
console.log(elementId + " found");
return ElementSearchStatus.Found;
}
else {
console.log("Search for " + elementId + " timed out after " + count + " tries.");
return ElementSearchStatus.Timeout;
}
}
else {
console.log("waiting for " + elementId + " after " + count + " of " + timeout);
return ElementSearchStatus.None;
}
}
function main() {
waitForElement("StartButton", 0, maxTimeout, function () {
console.log("found StartButton!");
DoOtherStuff("StartButton2")
});
}
function DoOtherStuff(elementId) {
waitForElement(elementId, 0, maxTimeout, function () {
console.log("found " + elementId);
DoOtherStuff("StartButton3");
});
}
</script>
</head>
<body>
<button type="button" id="StartButton" onclick="main();">Start Test</button>
<button type="button" id="StartButton2" onclick="alert('Hey ya Start Button 2');">Show alert</button>
</body>
</html>
一行使用Promise
const wait = t => new Promise(s => setTimeout(s, t, t));
带有中止信号的字体
const wait = (x: number, signal?: AbortSignal): Promise<number> => {
return new Promise((s, f) => {
const id = setTimeout(s, x, x);
signal?.addEventListener('abort', () => {
clearTimeout(id);
f('AbortError');
});
});
};
Demo
const wait=t=>new Promise(s=>setTimeout(s,t));//用途异步函数demo(){//倒计时设i=6;而(i-){等待等待(1000);控制台日志(i);}//数字0到5的总和,延迟1秒constsum=await[…Array(6).keys()].reduce(async(a,b)=>{a=等待a;等待等待(1000);常量结果=a+b;console.log(`${a}+${b}=${result}`);返回结果;},承诺.决议(0));console.log(“sum”,总和);}demo();
如果您使用的是Node.js,您可以看看fiber——一种对节点的原生C扩展,一种多线程模拟。
它允许您以阻塞光纤中的执行的方式进行真正的睡眠,但在主线程和其他光纤中是非阻塞的。
下面是他们自己自述文件中的一个例子:
// sleep.js
var Fiber = require('fibers');
function sleep(ms) {
var fiber = Fiber.current;
setTimeout(function() {
fiber.run();
}, ms);
Fiber.yield();
}
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
–结果如下:
$ node sleep.js
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
首先,应该使用setTimeout和setInterval,因为JavaScript具有回调性质。如果您想使用sleep(),则是控制流或代码架构不正确。
尽管如此,我想我仍然可以帮助实现两个睡眠。
1.我头顶上的假同步跑步:
// A module to do that //dual-license: MIT or WTF [you can use it anyhow and leave my nickname in a comment if you want to]
var _ = (function(){
var queue = [];
var play = function(){
var go = queue.shift();
if(go) {
if(go.a) {
go.f();
play();
}
else
{
setTimeout(play, go.t);
}
}
}
return {
go:function(f){
queue.push({a:1, f:f});
},
sleep:function(t){
queue.push({a:0, t:t});
},
playback:play
}
})();
[也可以自动播放]
// Usage
_.go(function(){
// Your code
console.log('first');
});
_.sleep(5000);
_.go(function(){
// Your code
console.log('next');
});
// This triggers the simulation
_.playback();
2.实际同步运行
有一天,我对它进行了很多思考,我在JavaScript中真正睡觉的唯一想法就是技术。
睡眠函数必须是同步Ajax调用,超时设置为睡眠值。这就是真正睡觉的唯一方法。
可以使用带有递增较大值的闭包调用setTimeout()。
var items = ['item1', 'item2', 'item3'];
function functionToExecute(item) {
console.log('function executed for item: ' + item);
}
$.each(items, function (index, item) {
var timeoutValue = index * 2000;
setTimeout(function() {
console.log('waited ' + timeoutValue + ' milliseconds');
functionToExecute(item);
}, timeoutValue);
});
结果:
waited 0 milliseconds
function executed for item: item1
waited 2000 milliseconds
function executed for item: item2
waited 4000 milliseconds
function executed for item: item3