在JavaScript中睡眠 - 在动作之间延迟

时间:2009-04-17 01:34:58

标签: javascript sleep

在执行其他操作之前,有没有办法让我在JavaScript中睡觉?

示例:

 var a = 1+3;
 // Sleep 3 seconds before the next action here
 var b = a + 4;

13 个答案:

答案 0 :(得分:123)

您可以使用setTimeout来达到类似的效果:

var a = 1 + 3;
var b;
setTimeout(function() {
    b = a + 4;
}, (3 * 1000));

这并没有真正“睡眠”JavaScript - 它只是在一定时间(以毫秒为单位)后执行传递给setTimeout的函数。尽管可以为JavaScript编写睡眠函数,但如果可能的话,最好使用setTimeout,因为它不会在睡眠期间冻结所有内容。

答案 1 :(得分:40)

如果您确实需要sleep()来测试某些内容。但请注意,在调试时大多数情况下它会崩溃浏览器 - 这可能就是你无论如何都需要它的原因。在生产模式中,我会注释掉这个功能。

function pauseBrowser(millis) {
    var date = Date.now();
    var curDate = null;
    do {
        curDate = Date.now();
    } while (curDate-date < millis);
}

请勿在循环中使用new Date(),除非您要浪费内存,处理能力,电池以及设备的使用寿命。

答案 2 :(得分:11)

ECMAScript 6版本,使用带有&#34;代码阻止&#34;:

的yield的生成器

因为最初的问题是在七年前发布的,所以我没有用确切的代码来回答,因为它太简单并且已经回答了。这应该有助于解决更复杂的问题,例如,如果您需要至少两次睡眠,或者您计划对异步执行进行排序。随意修改它以满足您的需求。

&#13;
&#13;
let sleeptime = 100
function* clock()
{
    let i = 0
    while( i <= 10000 )
    {
        i++
        console.log(i); // actually, just do stuff you wanna do.
        setTimeout(
            ()=>
            {
                clk.next()
            }
            , sleeptime
        )
        yield
    }
}

let clk = clock()
clk.next()
&#13;
&#13;
&#13;

function*

() => arrow function

您还可以通过Promises链接活动:

&#13;
&#13;
function sleep(ms)
{
    return(
        new Promise(function(resolve, reject)
        {
            setTimeout(function() { resolve(); }, ms);
        })
    );
}


sleep(1000).then(function()
{
    console.log('1')
    sleep(1000).then(function()
    {
        console.log('2')
    })
})
&#13;
&#13;
&#13;

或者更简单,更简洁的方式

&#13;
&#13;
function sleep(ms, f)
{
    return(
        setTimeout(f, ms)
    )
}


sleep(500, function()
{
    console.log('1')
    sleep(500, function()
    {
        console.log('2')
    })
})
console.log('Event chain launched')
&#13;
&#13;
&#13;

如果你只是等待某种情况发生,你可以这样等待

&#13;
&#13;
function waitTill(condition, thenDo)
{
    if (eval(condition))
    {
        thenDo()
        return
    }

    setTimeout(
        ()    =>
        {
            waitTill(condition, thenDo)
        }
        ,
        1
    )
}

x=0

waitTill(
    'x>2 || x==1'
    ,
    ()    =>
    {
        console.log("Conditions met!")
    }
)

// Simulating the change
setTimeout(
    () =>
    {
        x = 1
    }
    ,
    1000
)
&#13;
&#13;
&#13;

答案 3 :(得分:7)

2018年更新

最新的Safari,Firefox和Node.js现在也支持async / await / promises。

2017年更新

自问这个问题以来,JavaScript已经发展,现在有了生成器函数,新的async / await / Promise正在推出。下面有两个解决方案,一个具有生成器功能,可以在所有现代浏览器上运行,另一个使用新的async / await,这在任何地方都不受支持。

使用生成器函数:

'use strict';

let myAsync = (g) => (...args) => {
    let f, res = () => f.next(),
        sleep = (ms) => setTimeout(res, ms);
    f = g.apply({sleep}, args); f.next();
};

let myAsyncFunc = myAsync(function*() {
    let {sleep} = this;
    console.log("Sleeping");
    yield sleep(3000);
    console.log("Done");
});

myAsyncFunc();

使用async / await / Promises:

(自2017年1月起,支持Chrome,但不支持Safari,Internet Explorer,Firefox,Node.js)

'use strict';

function sleep(ms) {
  return new Promise(res => setTimeout(res, ms));
}

let myAsyncFunc = async function() {
  console.log('Sleeping');
  await sleep(3000);
  console.log('Done');
}

myAsyncFunc();

请注意这两种解决方案本质上都是异步的。这意味着myAsyncFunc(在两种情况下都会)在休眠时返回。

重要的是要注意,这个问题不同于 What is the JavaScript version of sleep()? ,其中请求者要求真正的睡眠(在进程上没有其他代码执行)而不是动作之间的延迟。

答案 4 :(得分:3)

如果你想要比setTimeoutsetInterval更少的笨重的函数,你可以将它们包装在只是颠倒参数顺序的函数中,并给它们提供好名字:

function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }

CoffeeScript版本:

after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms

然后,您可以很好地使用它们与匿名函数:

after(1000, function(){
    console.log("it's been a second");
    after(1000, function(){
        console.log("it's been another second");
    });
});

现在它很容易读作“经过N毫秒,......”(或“每N毫秒......”)

答案 5 :(得分:2)

另一种方法是使用Promise和setTimeout(请注意,您需要位于函数内部,并使用async关键字将其设置为异步):

async yourAsynchronousFunction () {

    var a = 1+3;

    await new Promise( (resolve) => {
        setTimeout( () => { resolve(); }, 3000);
    }

    var b = a + 4;

}

答案 6 :(得分:1)

您可以使用普通的javascript,这将在5秒钟后调用您的函数/方法:

setTimeout(()=> { your_function(); }, 5000);

答案 7 :(得分:1)

<label *ngIf="telefonos.errors?.required">
  your msg.
</label>
<label *ngIf="telefonos.controls[i].get('numeroCelular').errors?.required">
  your msg.
</label>

答案 8 :(得分:0)

有几种方法可以解决这个问题。如果我们使用select custId from testrecords where currentstatus='P' and category in ('A','B','C') group by custId having count(distinct category) = 3; 函数,让我们先了解它。 This function有三个参数: setTimeout function code (以毫秒为单位) )和 delay 。 由于功能代码参数是必需的,因此其他参数是可选的。 一旦您没有输入延迟,它将被设置为零。

有关parameters go to this link

的详细信息

简化版:

setTimeout()
  

输出:
  a = 4
  24 - &gt;活动超时列表的编号标识符
  b = 8


使用参数pass:

var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(function(){ 
    b = a + 4; 
    console.log('b = ' + b);
}, 1000);
  

输出:
  a = 4
  25 - &gt;活动超时列表的编号标识符
  b = 8



浏览器支持:

Chrome     Firefox     Edge     Safari     Opera
1.0        1.0         4.0      1.0        4.0

答案 9 :(得分:0)

这是我的模特,展示如何睡眠&#34;或&#34; DoEvents&#34;在javascript中使用生成器函数(ES6)。评论代码:

        caps = DesiredCapabilities().FIREFOX
        caps["pageLoadStrategy"] = "eager"
        fp = webdriver.FirefoxProfile('firefoxadblocked')

        proxyString = ad_proxy_array[0] + ':' + ad_proxy_array[1]

        caps['proxy'] = {
                    "proxyType": "manual",
                    "httpProxy": proxyString,
                    "ftpProxy": proxyString,
                    "sslProxy": proxyString
                }

答案 10 :(得分:0)

尝试此功能:

function delay(ms, cb) { setTimeout(cb, ms) }

如果您使用的是Babel:

const delay = (ms, cb) => setTimeout(cb, ms)

这是您的用法:

console.log("Waiting for 5 seconds.")
delay(5000, function() {
  console.log("Finished waiting for 5 seconds.")
})

这里是demo

答案 11 :(得分:0)

这是一种非常简单的方法,感觉像同步睡眠/暂停一样,但是是合法的js异步代码。

// Create a simple pause function
const pause = (timeoutMsec) => new Promise(resolve => setTimeout(resolve,timeoutMsec))

async function main () {
    console.log('starting');
    // Call with await to pause.  Note that the main function is declared asyc
    await pause(3*1000)
    console.log('done');
}

答案 12 :(得分:0)

这是使用setTimeout()的调用的基于Promise的sleep()的重写和演示。它还降级了对setTimeout()的常规调用。一旦运行它就不言自明了。 :)

function sleep(ms) {
    return new Promise(resolve => setTimeout(() => resolve(), ms))
}

console.log("Synchronous call 1");
sleep(4000)
.then(() => console.log("Asynchronous call 1"));
sleep(2000)
.then(() => console.log("Asynchronous call 2"));
console.log("Synchronous call 2");
sleep(3000)
.then(() => console.log("Asynchronous call 3"));
console.log("Synchronous call 3");
sleep(5000)
.then(() => console.log("Asynchronous call 4"))
.then(sleep(7000)
.then(()=>console.log("Asynchronous call 5")))
console.log("Synchronous call 4");
setTimeout(() => {console.log("Asynchronous call 6")}, 8000);
console.log("Synchronous call 5");

Image of its run on Repl.it