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

Jin*_*ong 119 javascript sleep

有没有办法在JavaScript执行另一个操作之前在JavaScript中睡觉?

例:

 var a = 1+3;
 // Sleep 3 seconds before the next action here
 var b = a + 4;
Run Code Online (Sandbox Code Playgroud)

Ste*_*son 128

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

var a = 1 + 3;
var b;
setTimeout(function() {
    b = a + 4;
}, (3 * 1000));
Run Code Online (Sandbox Code Playgroud)

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

  • 另请查看setInterval().它类似于setTimeout(),但是你的函数被多次调用(直到你停止它),如果你想在睡觉时做某事(比如进行进度更新,保持一些内部状态或其他),这很有用. (8认同)
  • 这不回答这个问题.这个问题要求"睡眠"等同于此. (4认同)
  • 除非,当然,除非某人确实想要一个阻塞循环。 (2认同)

Rod*_*igo 48

如果你真的需要一个sleep()公正的测试.但请注意,在调试时大多数情况下它会崩溃浏览器 - 这可能就是你无论如何都需要它的原因.在生产模式中,我将注释掉这个功能.

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

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

  • 这个答案值得更多的选票.主题问题正是这个答案的原因. (7认同)
  • @ 3.1415926535897932384626433833嗯,有人要求"睡眠"功能,这就是这里的内容.我用了一次,记不清究竟是为了什么样的调试.如果我再次需要它,我知道在哪里找到它.如果您更喜欢其他功能,那就是您的选择.能选择不是很好吗? (7认同)
  • “忙着等待”。 (2认同)
  • 您一直在制造的忙等待循环正是您希望它不会做的事情:它将耗尽处理能力、电池,甚至可能耗尽设备的使用寿命。它可能比“new Date()”使用内存,但这也可能取决于实现。对于调试代码来说还可以,**但是**不要考虑将它用于任何效率不高的事情。 (2认同)

Ího*_* Mé 11

ECMAScript 6版本,使用带有"代码阻塞"的yield的生成器:

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

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()
Run Code Online (Sandbox Code Playgroud)

功能*

()=>箭头功能

您还可以通过Promises链接事件:

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')
    })
})
Run Code Online (Sandbox Code Playgroud)

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

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')
Run Code Online (Sandbox Code Playgroud)

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

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
)
Run Code Online (Sandbox Code Playgroud)


nir*_*iry 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();
Run Code Online (Sandbox Code Playgroud)

使用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();
Run Code Online (Sandbox Code Playgroud)

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

重要的是要注意这个问题不同于什么是sleep()的JavaScript版本?请求者要求真正睡眠(在进程上没有其他代码执行)而不是动作之间的延迟.


use*_*237 6

这是一种非常简单的方法,“感觉”像同步睡眠/暂停,但却是合法的 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');
}
Run Code Online (Sandbox Code Playgroud)


Noe*_*out 5

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

async yourAsynchronousFunction () {

    var a = 1+3;

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

    var b = a + 4;

}
Run Code Online (Sandbox Code Playgroud)