我有一个代码需要在延迟说5000 ms后执行。目前我使用的是setTimeout但它是异步的,我希望执行等待它的返回。我尝试过使用以下内容:
function pauseComp(ms)
{
var curr = new Date().getTime();
ms += curr;
while (curr < ms) {
curr = new Date().getTime();
}
}
但是我想延迟的代码是使用raphaeljs绘制一些对象,并且显示不是很平滑。我正在尝试使用doTimeout插件。我只需要延迟一次,因为延迟和要延迟的代码都在循环中。我没有要求身份证,所以我没有使用它。 例如:
for(i; i<5; i++){ $.doTimeout(5000,function(){
alert('hi'); return false;}, true);}
等待5秒钟,然后给出第一个Hi,然后连续循环迭代在第一个之后立即显示警报。我想要它做的是等待5秒再次提醒警报等待然后提供警报等等。
任何提示/建议都表示赞赏!
答案 0 :(得分:42)
接受答案的变化与此一样好。
另外,我同意更喜欢setTimeout
和异步函数调用的注意事项,但有时例如,在构建测试时,您只需要一个同步等待命令......
function wait(ms) {
var start = Date.now(),
now = start;
while (now - start < ms) {
now = Date.now();
}
}
如果你想要它在几秒钟内,在while检查时将开始ms除以1000 ......
答案 1 :(得分:5)
JavaScript是一种单线程语言。您无法合并setTimeout
和同步处理。会发生什么,计时器将会失效,但JS引擎将等待处理结果,直到当前脚本完成。
如果你想要同步方法,只需直接调用方法!
如果要在setTimeout之后处理某些内容,请将其包含在内或从超时函数中调用它。
答案 2 :(得分:4)
如果您想利用新的async / await语法,可以将set timeout转换为promise,然后等待它。
function wait(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Done waiting");
resolve(ms)
}, ms )
})
}
(async function Main() {
console.log("Starting...")
await wait(5000);
console.log("Ended!")
})();
答案 3 :(得分:2)
非超时循环(检查时间或计数到1000000或其他)只是锁定浏览器。 setTimeout
(或$.doTimeout
插件)是最佳方式。
在循环中创建超时将不起作用,因为循环不等待先前的超时在继续之前发生,如您所发现的那样。尝试更像这样的东西:
// Generic function to execute a callback a given number
// of times with a given delay between each execution
function timeoutLoop(fn, reps, delay) {
if (reps > 0)
setTimeout(function() {
fn();
timeoutLoop(fn, reps-1, delay);
}, delay);
}
// pass your function as callback
timeoutLoop(function() { alert("Hi"); },
5,
5000);
(我只是快速地将它拼凑在一起,所以尽管我确信它有效,但它可以通过多种方式进行改进,例如,在“循环”中它可以将索引值传递给回调函数,以便您自己的代码知道它在哪个迭代。但希望它会让你开始。)
答案 4 :(得分:2)
我做了一个简单的同步超时功能。它以两种不同的方式工作,回调和非回调。
功能:
function wait(ms, cb) {
var waitDateOne = new Date();
while ((new Date()) - waitDateOne <= ms) {
//Nothing
}
if (cb) {
eval(cb);
}
}
回调示例:
wait(5000,"doSomething();");
非回调示例:
console.log("Instant!");
wait(5000);
console.log("5 second delay");
答案 5 :(得分:2)
const syncWait = ms => {
const end = Date.now() + ms
while (Date.now() < end) continue
}
用法:
console.log('one')
syncWait(5000)
console.log('two')
const asyncWait = ms => new Promise(resolve => setTimeout(resolve, ms))
用法:
(async () => {
console.log('one')
await asyncWait(5000)
console.log('two')
})()
const delayedCall = (array, ms) =>
array.forEach((func, index) => setTimeout(func, index * ms))
用法:
delayedCall([
() => console.log('one'),
() => console.log('two'),
() => console.log('three'),
], 5000)
答案 6 :(得分:1)
使用新的Atomics API,您可以启动同步延迟而不会出现性能峰值:
const sleep = milliseconds => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds)
sleep(5000) // Sleep for 5 seconds
console.log("Executed after 5 seconds!")
答案 7 :(得分:0)
以下是如何使用JQuery doTimeout
插件
jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] );
来自docs:“如果回调返回true, doTimeout
循环将在延迟后再次执行,创建一个轮询循环,直到回调为止返回非真值。“
var start = Date.now();
console.log("start: ", Date.now() - start);
var i = 0;
$.doTimeout('myLoop', 5000, function() {
console.log(i+1, Date.now() - start);
++i;
return i == 5 ? false : true;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-dotimeout/1.0/jquery.ba-dotimeout.min.js"></script>
答案 8 :(得分:-1)
使用函数发生器的解决方案。证明它可以做到。 不推荐。
function wait(miliseconds){
const gen = function * (){
const end = Date.now() + miliseconds;
while(Date.now() < end){yield};
return;
}
const iter = gen();
while(iter.next().done === false);
}
console.log("done 0");
wait(1000);
console.log("done 1");
wait(2000);
console.log("done 2");
答案 9 :(得分:-1)
节点解决方案
使用fs.existsSync()进行延迟
const fs = require('fs');
const uuidv4 = require('uuid/v4');
/**
* Tie up execution for at-least the given number of millis. This is not efficient.
* @param millis Min number of millis to wait
*/
function sleepSync(millis) {
if (millis <= 0) return;
const proceedAt = Date.now() + millis;
while (Date.now() < proceedAt) fs.existsSync(uuidv4());
}
fs.existsSync(uuidv4())用于执行以下操作: