使用 JavaScript 在特定延迟后执行脚本

Posted

技术标签:

【中文标题】使用 JavaScript 在特定延迟后执行脚本【英文标题】:Execute script after specific delay using JavaScript 【发布时间】:2010-09-06 16:38:58 【问题描述】:

有没有类似于 jQuery delay()wait()javascript 方法(将脚本的执行延迟特定时间)?

【问题讨论】:

【参考方案1】:

只是补充一下其他人对setTimeout 的看法: 如果以后要调用带参数的函数,就需要设置一些匿名函数调用。

您需要将该函数作为参数传递,以便稍后调用它。实际上,这意味着名称后面没有括号。以下将立即调用警报,并显示“Hello world”:

var a = "world";
setTimeout(alert("Hello " + a), 2000);

要解决此问题,您可以输入函数的名称(如 Flubba 所做的那样),也可以使用匿名函数。如果需要传递参数,则必须使用匿名函数。

var a = "world";
setTimeout(function()alert("Hello " + a), 2000);
a = "Stack Overflow";

但是,如果您运行该代码,您会注意到 2 秒后弹出窗口会显示“Hello Stack Overflow”。这是因为变量 a 的值在那两秒内发生了变化。要让它在两秒后说“Hello world”,您需要使用以下代码 sn-p:

function callback(a)
    return function()
        alert("Hello " + a);
    

var a = "world";
setTimeout(callback(a), 2000);
a = "Stack Overflow";

它将等待 2 秒,然后弹出“Hello world”。

【讨论】:

【参考方案2】:

有以下几点:

setTimeout(function, milliseconds);

函数可以传递函数执行的时间。

请参阅:Window setTimeout() Method。

【讨论】:

它不是一个被执行的表达式,它是一个函数。 @Marius 的回答说明了这一点。 这不是延迟,而是分叉。延迟应该在同一个线程中工作。 这将立即执行function_reference。要“工作”(异步),应将其表述为: setTimeout(function () MethodToCall(); , 1000); 我想指出我们正在谈论 JavaScript;提出“线程”或它应该“同步”工作可能是真的技术上语义上但并不真正适合JavaScript的上下文,考虑到确实没有使用其中任何一种方法实现延迟的方法(您不会像在其他语言中那样在 JS 中创建“线程”)。此外,这不会立即执行function_reference,除非您包含()。 IE。 function_reference 只是一个参考;传入function_reference() 将立即调用该函数。【参考方案3】:

只是为了扩展一点......您可以直接在setTimeout调用中执行代码,但正如@patrick所说,您通常会分配一个回调函数,就像这样。时间是毫秒

setTimeout(func, 4000);
function func() 
    alert('Do stuff here');

【讨论】:

【参考方案4】:

如果你真的想要一个阻塞(同步)delay 函数(不管怎样),为什么不做这样的事情:

<script type="text/javascript">
    function delay(ms) 
        var cur_d = new Date();
        var cur_ticks = cur_d.getTime();
        var ms_passed = 0;
        while(ms_passed < ms) 
            var d = new Date();  // Possible memory leak?
            var ticks = d.getTime();
            ms_passed = ticks - cur_ticks;
            // d = null;  // Prevent memory leak?
        
    

    alert("2 sec delay")
    delay(2000);
    alert("done ... 500 ms delay")
    delay(500);
    alert("done");
</script>

【讨论】:

此解决方案的困难在于它主动使用处理器,这会导致功耗增加和其他线程/进程(例如其他选项卡、其他程序)可用的资源减少。相比之下,睡眠会暂时挂起线程对系统资源的使用。 最好使用 Date.now() 而不是 new Date() 并且不要考虑内存泄漏 当然它是 CPU 密集型的,但是对于快速和肮脏的测试来说它可以工作 一个更紧凑的例程:function delay(ms) var start_time = Date.now(); while (Date.now() - start_time ;(function()function a(b,a)!0!==a&amp;&amp;(b*=1E3);for(var c=Date.now();Date.now()-c&lt;b;);window.hasOwnProperty("delay")||(window.delay=a))(); 使用秒或毫秒。 3 秒示例:delay(3); 500 毫秒示例:delay(500, true);【参考方案5】:

您需要使用setTimeout 并传递一个回调函数。你不能在 javascript 中使用 sleep 的原因是你会阻止整个页面在此期间做任何事情。不是一个好计划。使用 Javascript 的事件模型并保持快乐。不要打架!

【讨论】:

它仍然对测试有用。就像在发出新的 HTTP 请求之前将表单提交延迟几秒钟以评估页面更改。 @rushinge 然后设置回调以提交表单并禁用默认表单提交【参考方案6】:

您还可以使用window.setInterval() 定期重复运行某些代码。

【讨论】:

setInterval() 不应该被使用,而应该使用 setTimeout setTimeout() 执行一次,setInterval() 重复执行。如果你希望你的代码每 5 秒运行一次,setInterval() 就是为这项工作而制作的。【参考方案7】:

为了补充之前的cmets,我想说以下几点:

JavaScript 中的setTimeout() 函数本身并不会暂停脚本的执行,而只是告诉编译器在将来的某个时间执行代码。

没有一个函数可以真正暂停 JavaScript 内置的执行。但是,您可以编写自己的函数,通过使用 Date() 函数并添加您需要的时间间隔来执行无条件循环之类的操作。

【讨论】:

【参考方案8】:

如果你只需要测试延迟,你可以使用这个:

function delay(ms) 
   ms += new Date().getTime();
   while (new Date() < ms)

如果你想延迟 2 秒,你可以这样做:

delay(2000);

但可能不是最适合生产的。更多关于 cmets 的内容

【讨论】:

嗯,这是一个繁忙的循环,会耗尽笔记本电脑和其他移动设备的电池,并且可能还会阻止 UI 响应(甚至显示)。 @U2744SNOWFLAKE 有道理。已经更新了答案,因为我使用这个功能:) 在开发中工作得很好,可以提供快速而肮脏(和临时)的解决方案。【参考方案9】:

为什么你不能把代码放在 Promise 后面? (在我脑海中输入)

new Promise(function(resolve, reject) 
  setTimeout(resolve, 2000);
).then(function() 
  console.log('do whatever you wanted to hold off on');
);

【讨论】:

【参考方案10】:

简单的回复是:

setTimeout(
    function () 
        x = 1;
    , 1000);

上面的函数等待 1 秒(1000 毫秒)然后将 x 设置为 1。 显然这是一个例子;你可以在匿名函数中做任何你想做的事情。

【讨论】:

【参考方案11】:

我真的很喜欢 Maurius 的解释(最高赞成的回应),其中有三种不同的调用 setTimeout 的方法。

在我的代码中,我想在 AJAX 保存事件完成后自动自动导航到上一页。保存事件的完成在 CSS 中有一个轻微的动画,表示保存成功。

在我的代码中,我发现前两个示例之间存在差异:

setTimeout(window.history.back(), 3000);

这个不等待超时——无论我为延迟输入什么数字,几乎都会立即调用 back()。

但是,将其更改为:

setTimeout(function() window.history.back(), 3000);

这正是我所希望的。

这不是特定于 back() 操作,alert() 也是如此。基本上在第一种情况下使用alert(),延迟时间被忽略。当我关闭弹出窗口时,CSS 的动画会继续。

因此,即使您使用内置函数而不使用参数,我也会推荐他描述的第二种或第三种方法。

【讨论】:

【参考方案12】:

我有一些想要运行的 ajax 命令,中间有一些延迟。这是一种方法的简单示例。我准备好因为我的非传统方法而被撕成碎片。 :)

//  Show current seconds and milliseconds
//  (I know there are other ways, I was aiming for minimal code
//  and fixed width.)
function secs()

    var s = Date.now() + ""; s = s.substr(s.length - 5);
  return s.substr(0, 2) + "." + s.substr(2);


//  Log we're loading
console.log("Loading: " + secs());

//  Create a list of commands to execute
var cmds = 
[
    function()  console.log("A: " + secs()); ,
    function()  console.log("B: " + secs()); ,
    function()  console.log("C: " + secs()); ,
    function()  console.log("D: " + secs()); ,
    function()  console.log("E: " + secs()); ,
  function()  console.log("done: " + secs()); 
];

//  Run each command with a second delay in between
var ms = 1000;
cmds.forEach(function(cmd, i)

    setTimeout(cmd, ms * i);
);

// Log we've loaded (probably logged before first command)
console.log("Loaded: " + secs());

您可以复制代码块并将其粘贴到控制台窗口中,然后查看如下内容:

Loading: 03.077
Loaded: 03.078
A: 03.079
B: 04.075
C: 05.075
D: 06.075
E: 07.076
done: 08.076

【讨论】:

【参考方案13】:

延迟调用函数的最简单解决方案是:

function executeWithDelay(anotherFunction) 
    setTimeout(anotherFunction, delayInMilliseconds);

【讨论】:

【参考方案14】:

延时功能:

/**
 * delay or pause for some time
 * @param number t - time (ms)
 * @return Promise<*>
 */
const delay = async t => new Promise(resolve => setTimeout(resolve, t));

async 函数内部的用法:

await delay(1000);

【讨论】:

【参考方案15】:

正如其他人所说,setTimeout 是您最安全的选择 但有时你不能将逻辑分离到一个新函数中,然后你可以使用 Date.now() 来获取毫秒并自己做延迟......

function delay(milisecondDelay) 
   milisecondDelay += Date.now();
   while(Date.now() < milisecondDelay)


alert('Ill be back in 5 sec after you click OK....');
delay(5000);
alert('# Im back # date:' +new Date());

【讨论】:

以上是关于使用 JavaScript 在特定延迟后执行脚本的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 获取延迟

JavaScript值延迟脚本和异步脚本

js的执行和调试

JavaScript高级程序设计-html中使用JavaScript

JavaScript高级程序设计

JavaScript看这一篇就够了,简单全面一发入魂