Что такое JavaScript-версия sleep ()? - PullRequest
1903 голосов
/ 04 июня 2009

Есть ли лучший способ создать sleep в JavaScript, чем следующая pausecomp функция ( взято отсюда )?

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

Это не дубликат Сон в JavaScript - задержка между действиями ; Мне нужен реальный сон в середине функции, а не задержка перед выполнением фрагмента кода.

Ответы [ 73 ]

27 голосов
/ 04 ноября 2014

Вот простое решение с использованием синхронного XMLHttpRequest:

function sleep(n){
  var request = new XMLHttpRequest();
  request.open('GET', '/sleep.php?n=' + n, false);  // `false` makes the request synchronous
  request.send(null);
}

содержимое sleep.php:

<?php sleep($_GET['n']);

Теперь позвоните с: сна (5);

18 голосов
/ 12 ноября 2016

лично мне нравится простое:

function sleep(seconds){
    var waitUntil = new Date().getTime() + seconds*1000;
    while(new Date().getTime() < waitUntil) true;
}

тогда:

sleep(2); // Sleeps for 2 seconds

Я все время использую его для создания фальшивого времени загрузки при создании скриптов в P5js

18 голосов
/ 04 июня 2009

Первый:

Определите функцию, которую вы хотите выполнить следующим образом:

function alertWorld(){
  alert("Hello World");
}

Затем запланируйте его выполнение с помощью метода setTimeout:

setTimeout(alertWorld,1000)

Обратите внимание на две вещи

  • второй аргумент - время в миллисекундах
  • в качестве первого аргумента вы должны передать только имя (ссылку) функции без скобок
15 голосов
/ 08 августа 2011

Лучшее решение для того, чтобы все выглядело так, как того хочет большинство людей, - это использование анонимной функции:

alert('start');
var a = 'foo';
//lots of code
setTimeout(function(){  //Beginning of code that should run AFTER the timeout
    alert(a);
    //lots more code
},5000);  // put the timeout here

Это, вероятно, ближе всего к тому, что просто делает то, что вы хотите.

Обратите внимание, что если вам нужно несколько снов, это может привести к неприятным последствиям, и вам, возможно, придется пересмотреть свой дизайн.

10 голосов
/ 09 июля 2015

Я бы инкапсулировал setTimeOut в Promise для согласованности кода с другими асинхронными задачами: Демонстрация в Fiddle

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

Используется так:

sleep(2000).then(function() { 
   // Do something
});

Синтаксис легко запомнить, если вы использовали Обещания.

9 голосов
/ 18 мая 2013

Для браузеров я согласен с тем, что setTimeout и setInterval - это то, что нужно.

Но для серверного кода может потребоваться функция блокировки (например, чтобы вы могли эффективно синхронизировать потоки).

Если вы используете node.js и meteor, возможно, вы столкнулись с ограничениями использования setTimeout в волокне. Вот код для сна на стороне сервера.

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

См .: https://github.com/laverdet/node-fibers#sleep

9 голосов
/ 25 июня 2014

Большинство ответов здесь ошибочны или, по крайней мере, устарели. Нет причин, по которым javascript должен быть однопоточным, и на самом деле это не так. Сегодня все основные браузеры поддерживают рабочих, до этого другие среды выполнения javascript, такие как Rhino и Node.js, поддерживали многопоточность.

«Javascript является однопоточным» не является правильным ответом. Например, выполнение функции сна на рабочем месте не будет блокировать любой код, выполняющийся в потоке пользовательского интерфейса.

В более новых средах выполнения, поддерживающих генераторы и выход, можно было бы использовать аналогичные функции для функции сна в однопоточной среде:

// This is based on the latest ES6 drafts.
// js 1.7+ (SpiderMonkey/Firefox 2+) syntax is slightly different

// run code you want to sleep here (ommit star if using js 1.7)
function* main(){
    for (var i = 0; i < 10; i++) {
        // to sleep for 10 milliseconds 10 times in a row
        yield 10;
    }

    yield 5;
    console.log('I just slept 5 milliseconds!');
}

// resume the given generator after ms milliseconds
function resume(ms, generator){
    setTimeout(function(){
        // ommit .value if using js 1.7
        var nextSleep = generator.next().value;
        resume(nextSleep, generator);
    }, ms);
}

// initialize generator and get first sleep for recursive function
var
    generator = main(),
    firstSleep = generator.next().value;

// initialize recursive resume function
resume(firstSleep, generator);

Эта имитация сна отличается от настоящей функции сна, поскольку она не блокирует поток. Это просто сахар поверх текущей функции javascript setTimeout. Этот тип функциональности был реализован в Task.js и должен работать сегодня в Firefox.

8 голосов
/ 10 ноября 2009

Я искал / гуглил довольно много веб-страниц на javascript sleep / wait ... и НЕТ ответа, если вы хотите, чтобы javascript "RUN, DELAY, RUN" ... то, что большинство людей получили, было либо RUN (бесполезные вещи), RUN "или" RUN, RUN + отложенный запуск "....

Итак, я съел несколько гамбургеров и подумал ::: Вот решение, которое работает ... но вы должны нарезать свои текущие коды ... ::: да, я знаю, это просто легче читать рефакторинг ... все же ...

// ......................................... // example1:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setInterval
var i = 0;

function run() {
    //pieces of codes to run
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i >2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==5){document.getElementById("id1").innerHTML= "<p>all code segment finished running</p>"; clearInterval(t); } //end interval, stops run
    i++; //segment of code finished running, next...
}

run();
t=setInterval("run()",1000);

</script>
</body>
</html>

// .................................... // example2:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function run() {
    //pieces of codes to run, can use switch statement
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(1000);}
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(2000);}
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(3000);}
    if (i==3){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>";} //stops automatically
    i++;
}

function sleep(dur) {t=setTimeout("run()",dur);} //starts flow control again after dur

run(); //starts
</script>
</body>
</html>

// ................. example3:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function flow() {
    run(i);
    i++; //code segment finished running, increment i; can put elsewhere
    sleep(1000);
    if (i==5) {clearTimeout(t);} //stops flow, must be after sleep()
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow
</script>
</body>
</html>

// .............. Example4:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout, switch
var i = 0;

function flow() {
    switch(i)
    {
        case 0:
            run(i);
            sleep(1000);
            break;
        case 1:
            run(i);
            sleep(2000);
            break;
        case 5:
            run(i);
            clearTimeout(t); //stops flow
            break;
        default:
            run(i);
            sleep(3000);
            break;
    }
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    i++; //current segment of code finished running, next...
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow control for first time...
</script>
</body>
</html>
8 голосов
/ 09 ноября 2013
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
6 голосов
/ 21 июня 2011

Я могу понять назначение функции сна, если вам приходится иметь дело с синхронным выполнением. Функции setInterval и setTimeout создают поток параллельного выполнения, который возвращает последовательность выполнения обратно в основную программу, что неэффективно, если вам приходится ждать определенного результата. Конечно, можно использовать события и обработчики, но в некоторых случаях это не то, что предназначено.

...