Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 代码执行中的同步延迟_Javascript_Jquery_Settimeout - Fatal编程技术网

Javascript 代码执行中的同步延迟

Javascript 代码执行中的同步延迟,javascript,jquery,settimeout,Javascript,Jquery,Settimeout,我有一个代码需要在一些延迟后执行,比如5000毫秒。目前我正在使用setTimeout,但它是异步的,我希望执行等待返回。我已尝试使用以下方法: function pauseComp(ms) { var curr = new Date().getTime(); ms += curr; while (curr < ms) { curr = new Date().getTime(); } } 函数pauseComp(毫秒)

我有一个代码需要在一些延迟后执行,比如5000毫秒。目前我正在使用setTimeout,但它是异步的,我希望执行等待返回。我已尝试使用以下方法:

function pauseComp(ms) 
 {
     var curr = new Date().getTime();
     ms += curr;
     while (curr   < ms) {
         curr = new Date().getTime();
     }
 } 
函数pauseComp(毫秒)
{
var curr=new Date().getTime();
ms+=电流;
而(电流<毫秒){
curr=新日期().getTime();
}
} 
但是我想延迟的代码是使用raphaeljs绘制一些对象,显示一点也不平滑。我正在尝试使用doTimeout插件。我只需要延迟一次,因为延迟和要延迟的代码都在一个循环中。我没有身份证的要求,所以我没有使用它。 例如:

for(i; i<5; i++){ $.doTimeout(5000,function(){
         alert('hi');  return false;}, true);}

for(i;iJavaScript是一种单线程语言。您不能将
setTimeout
和同步处理结合起来。将会发生的事情是,计时器将失效,但JS引擎将等待处理结果,直到当前脚本完成

如果需要同步方法,只需直接调用该方法

如果您想在setTimeout之后处理某些内容,请将其包括在内或从timeout函数调用它。

非超时循环(检查时间或计数为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);

(我只是快速拼凑了一下,所以尽管我相信它可以工作,但它可以在几个方面得到改进,例如,在“循环”中,它可以将索引值传递到回调函数中,以便您自己的代码知道它将进行哪一次迭代。但希望它能让您开始。)

接受答案的变化与此答案一样好

此外,我同意优先选择
setTimeout
和异步函数调用的警告,但有时,例如,在构建测试时,您只需要一个同步等待命令

function wait(ms) {
    var start = Date.now(),
        now = start;
    while (now - start < ms) {
      now = Date.now();
    }
}
函数等待(毫秒){
var start=Date.now(),
现在=开始;
同时(现在-开始<毫秒){
now=Date.now();
}
}

如果您想在几秒钟内完成,请在while check上将start ms除以1000…

我制作了一个简单的同步超时函数。它有两种不同的工作方式,回调和非回调

功能:

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");

下面是如何使用JQuery
doTimeout
插件

jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] );
从:“如果回调返回true,则在延迟后,
doTimeout
循环将再次执行,创建轮询循环,直到回调返回非true值。”

var start=Date.now();
log(“开始:”,Date.now()-start);
var i=0;
$.doTimeout('myLoop',5000,function(){
log(i+1,Date.now()-start);
++一,;
返回i==5?假:真;
});

如果您想利用新的async/await语法,可以将set timeout转换为承诺,然后等待它

函数等待(毫秒){
返回新承诺((解决、拒绝)=>{
设置超时(()=>{
console.log(“完成等待”);
解析(毫秒)
},ms)
})
}  
(异步函数Main(){
日志(“正在启动…”)
等待等待(5000);
log(“结束!”)
})();

使用函数生成器的解决方案。以表明它可以完成。不推荐使用

功能等待(毫秒){
常数根=函数*(){
const end=Date.now()+毫秒;
while(Date.now()
同步等待(仅用于测试!): 异步等待: 用法:

console.log('one')
syncWait(5000)
console.log('two')
(async () => {
    console.log('one')
    await asyncWait(5000)
    console.log('two')
})()
delayedCall([
    () => console.log('one'),
    () => console.log('two'),
    () => console.log('three'),
], 5000)
备选方案(异步): 用法:

console.log('one')
syncWait(5000)
console.log('two')
(async () => {
    console.log('one')
    await asyncWait(5000)
    console.log('two')
})()
delayedCall([
    () => console.log('one'),
    () => console.log('two'),
    () => console.log('three'),
], 5000)

节点解决方案

使用fs.existsSync()延迟

const fs=require('fs');
const uuidv4=require('uuid/v4');
/**
*将执行绑定到至少给定的毫秒数。这是无效的。
*@param毫秒最小等待毫秒数
*/
函数休眠同步(毫秒){

如果(毫秒使用新的Atomics API,您可以启动同步延迟而不会出现性能峰值:

const sleep=millides=>Atomics.wait(新的Int32Array(新的SharedArrayBuffer(4)),0,0,毫秒)
睡眠(5000)//睡眠5秒
log(“5秒后执行!”)

除了setTimeout是一个更好的选择,OP请求是一个同步方法。@ThinkBonobo回答correctly@robsonrosa-OP还说“我想延迟的代码是使用raphaeljs绘制一些对象,显示一点也不平滑”。您不能使用同步代码并绘制内容,因为在同步代码完成之前,屏幕不会重新绘制。仅仅因为OP要求某些内容是不可能的。用户正在专门寻找同步解决方案-setTimeout不是synchronous@Ryan-根据我之前的评论,只是因为他们要求som这是不可能的。同步延迟不能与他们正在进行的绘图共存,他们抱怨绘图不够平滑。请使用
cb()
而不是
eval(db)
。将脚本保存为字符串不是一个好的做法。用法:
wait(5000,function(){console.log(“test!”)
。顺便说一句,如果需要回调,最好使用setTimeout。我想使用
requestAnimationFrame(function(){})
可能比
while
循环中的
nothing
要好,在while循环中什么都不做会耗费大量cpu。请注意cpu的使用。当然,@JosephLust。它应该只用于测试而不是生产代码的另一个原因。这个生成器函数没有意义,它可以简单地内联。这也是同样的道理与其他ans中一样的粘连
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());
}