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

IT技术 javascript sleep
2021-02-06 13:43:09

有没有一种方法可以让我在 JavaScript 执行另一个操作之前先睡一觉?

例子:

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

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

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

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

虽然这个答案与问题所问的不匹配,但它比循环和比较 Date.now() 更有用。没人用什么阻塞循环实现睡眠。
2021-03-10 13:43:09
除非,当然,阻挡环路正是有人想什么。
2021-03-26 13:43:09
这不能回答问题。这个问题要求一个“睡眠”等价物,而这不是。
2021-04-02 13:43:09
也看看 setInterval()。它类似于 setTimeout(),但是你的函数被多次调用(直到你停止它),如果你想在睡觉时做一些事情(比如做进度更新,保持一些内部状态,或者其他什么),这很有用。
2021-04-09 13:43:09

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

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

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

@3.1415926535897932384626433833 好吧,有人要求“睡眠”功能,这就是这里的内容。用过一次,记不清具体是什么调试用的了。如果我再次需要它,我确切地知道在哪里可以找到它。如果您更喜欢其他功能,那是您的选择。能够选择不是很好吗?
2021-03-16 13:43:09
“忙着等待”。
2021-03-24 13:43:09
您一直在制造的忙碌等待循环正是您希望它不会做的事情:它会耗尽处理能力、电池,甚至可能会耗尽设备的使用寿命。它可能比 使用内存new Date(),但这也可能取决于实现。可以调试代码,甚至不要考虑在任何半途而废的情况下使用它。
2021-03-26 13:43:09
@OkiErieRinaldi 那里没有递归,只是一个循环。
2021-03-27 13:43:09
这个答案值得更多选票。给这个问题加星标只是这个答案的原因。
2021-04-06 13:43:09

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()

功能*

() => 箭头函数

您还可以通过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')
    })
})

或者更简单,更不花哨的方式是

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')

如果你只是在等待某些条件发生,你可以像这样等待

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
)

2018年更新

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

使用异步/等待/Promise:

(截至 1/2017,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();

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

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

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

我在寻找解决方案时错过了这个答案并重新发明了自行车 :D 如果我能在它之前看到它会节省我几个小时!!点赞!
2021-03-27 13:43:09
到目前为止最好的答案!我花了 30 分钟到处搜索找到那个..大谢谢!!!
2021-04-03 13:43:09
let co = gen => (...args) => { let iter = gen(...args); let resume = () => new Promise((resolve, reject) => { let result = iter.next(); if (result.done) resolve(result.value); else Promise.resolve(result.value).then(resume).then(resolve, reject); }); return resume(); };会让你let asyncAdd = co(function* (a, b) { console.log('Sleeping'); yield sleep(3000); console.log('Done'); return a + b; }); asyncAdd(3, 4).then(console.log);使用sleep()来自第二个代码块的定义
2021-04-09 13:43:09

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

async yourAsynchronousFunction () {

    var a = 1+3;

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

    var b = a + 4;

}