Что такое JavaScript-версия sleep ()?

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

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

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

4.06.2009 14:41:10
Это должно быть установлено в середине времени, если я использую setTimeout, то while будет продолжать обрабатывать и ставить в очередь больше setTimeouts, которые в конечном итоге будут выполняться одновременно и создавать некоторый параллелизм между ними
fmsf 4.06.2009 14:44:51
Это ужасное решение - вы будете жевать циклы обработки, ничего не делая.
17 of 26 4.06.2009 14:47:02
Единственная цель для сна - опрос или ожидание обратного вызова - setInterval и setTimeout работают лучше, чем этот.
annakata 4.06.2009 14:50:30
Вероятно, вы можете делать то, что вы хотите с продолжением передачи стиля в JavaScript. Посмотрите на эту статью.
Ognyan Dimitrov 15.05.2015 08:02:45
30 ОТВЕТОВ
РЕШЕНИЕ

2017 - 2019 обновление

С 2009 года, когда был задан этот вопрос, JavaScript значительно эволюционировал. Все остальные ответы сейчас устарели или слишком сложны. Вот текущая лучшая практика:

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

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two seconds later, showing sleep in a loop...');

  // Sleep in loop
  for (let i = 0; i < 5; i++) {
    if (i === 3)
      await sleep(2000);
    console.log(i);
  }
}

demo();

Это оно. await sleep(<duration>),

Или как однострочник:

await new Promise(r => setTimeout(r, 2000));

Обратите внимание, что,

  1. awaitможет выполняться только в функциях с префиксом asyncключевого слова или на верхнем уровне вашего сценария в некоторых средах (например, консоль Chrome DevTools или Runkit).
  2. awaitтолько приостанавливает текущую asyncфункцию

Две новые функции JavaScript помогли написать эту «спящую» функцию:

Совместимость

Если по какой-то странной причине вы используете Node старше 7 лет ( срок действия которого истек ) или нацелены на старые браузеры, то async/ awaitвсе еще можно использовать через Babel (инструмент, который перенесет JavaScript + новые функции в обычный старый JavaScript) , с transform-async-to-generatorплагином.

2448
18.12.2019 15:56:05
Отличный материал здесь. Интересно, как это влияет или связано с «активными» / «неактивными» состояниями современных браузеров после того, как JS вызывает «спящий» режим? Может ли браузер блокировать спящий режим, как и ожидалось для обычного JS, для последующего вызова, когда он становится «активным», или у него другое поведение?
Andre Canilho 12.10.2016 02:16:36
Какова текущая поддержка браузера для этого? Я бы не считал предыдущие решения «устаревшими», пока это решение не поддерживается подавляющим большинством браузеров или, по крайней мере, всеми распространенными. Наоборот, я бы посчитал это решение интересным, но непригодным / непрактичным, пока оно не получит широкую поддержку.
Alvin Thompson 27.12.2016 17:56:41
Это не «настоящий сон» и не отвечает на вопрос. Человек, который спросил, четко определил различие между stackoverflow.com/questions/758688/sleep-in-javascript и его вопросом. В реальном сне никакой другой код не может быть выполнен (кроме как в другом потоке). Этот ответ хорош для другого вопроса.
niry 11.01.2017 17:00:05
@jacroe - транспортер обрабатывает функции стрелок, а также выполняет асинхронное / ожидание (что в любом случае вызывает рвоту в IE)
Jaromanda X 30.05.2017 08:39:21
@niry JavaScript, будучи однопоточным языком, не очень подходит для «реального» сна, поскольку он работает в том же потоке, что и пользовательский интерфейс, и может вызвать не отвечающие веб-страницы.
Patrick Roberts 13.09.2018 14:18:29

Ради любви к $ DEITY, пожалуйста, не делайте функцию сна с занятым ожиданием. setTimeoutи setIntervalделай все что нужно.

var showHide = document.getElementById('showHide');
setInterval(() => {
    showHide.style.visibility = "initial";
    setTimeout(() => {
        showHide.style.visibility = "hidden"
    }, 1000);
    ;
}, 2000);   
<div id="showHide">Hello! Goodbye!</div>

Каждые две секунды интервал скрывает текст на одну секунду. Здесь показано, как использовать setInterval и setTimeout для отображения и скрытия текста каждую секунду.

132
19.10.2019 21:39:10
Ну, не совсем все: setInterval производит намного лучшее впечатление от опроса.
annakata 4.06.2009 14:48:48
Что бы этот кусок кода не сдерживал в движке JavaScript?
Deniz Dogan 4.06.2009 14:51:20
Если вам не нужен сон, чтобы быть синхронным, то в этом случае это совершенно правильный вопрос.
Aaron Dufour 21.09.2011 16:54:02
Я думаю, что многие из нас могут забыть, что JavaScript не является языком только для браузера. Этот чувак может создавать утилиту командной строки Node, которая требует короткой паузы без необходимости решать все проблемы с областями видимости переменных, которые идут с setTimeout.
Phil LaNasa 2.03.2014 12:07:49
@PhilLaNasa: Если синтаксическое закрытие все еще пугает, нужно серьезно согнуться и проработать Узел 101.
chaos 3.03.2014 16:47:28

Вы не можете так спать в JavaScript, или, скорее, не должны. Запуск цикла sleep или while приведет к зависанию браузера пользователя до завершения цикла.

Используйте таймер, как указано в ссылке, на которую вы ссылались.

6
4.06.2009 14:46:51

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

Каждый раз, когда я хотел поспать в середине своей функции, я использовал рефакторинг setTimeout().

редактировать

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

Написание функции сна просто и стало еще удобнее с обещаниями JavaScript:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});
657
23.12.2019 15:13:30
В порядке закрытия. function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
chaos 8.04.2010 03:27:18
хорошо, а что если код не предназначен для использования на веб-странице?
Eugenio Miró 22.07.2010 15:23:46
@ EugenioMiró, если код не предназначен для использования на веб-странице, пусть объектная модель хоста реализует спящий метод. - Я думаю, что вопрос направлен на DOM, который подвержен JavaScript на веб-страницах.
BrainSlugs83 24.09.2011 00:57:45
@Nosredna да, мы понимаем, как делать асинхронные вызовы, это не помогает нам спать (). Я хочу, чтобы мои звонки выполнялись в определенном порядке, а данные возвращались в определенном порядке. Я на 5 уровней в глубине цикла. Я хочу заблокировать исполнение. Истинный метод сна не будет «тормозить браузер», управление спящими руками обратно к браузеру и любым другим потокам, которым требуется процессорное время, пока оно все еще блокируется.
BrainSlugs83 24.09.2011 00:59:33
это не ответ на вопрос.
TMS 24.11.2011 13:22:23

Первый:

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

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

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

setTimeout(alertWorld,1000)

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

  • второй аргумент - время в миллисекундах
  • в качестве первого аргумента вы должны передать только имя (ссылку) функции без скобок
20
4.06.2009 14:47:52

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

3
4.06.2009 14:48:57
Javascript предназначен не только для веб-страниц, но и для полного перевода, который можно использовать, например, с wscript. -1 для тебя
Eugenio Miró 22.07.2010 15:22:10
Что если вы пишете служебный скрипт в Node.js и вам просто нужно подождать, прежде чем вызывать вечный инструмент или конечную точку?
Dan Dascalescu 8.10.2016 22:51:45
Скимон здесь (я думаю, что я по какой-то причине потерял эту учетную запись), так или иначе, я думаю, что упоминание Node JS в ответ на 7-летний ответ - НЕМНОГО несправедливо.
Scimon Proctor 10.10.2016 11:39:25

Я согласен с другими постерами, плохой сон - это просто плохая идея.

Однако setTimeout не задерживает выполнение, он выполняет следующую строку функции сразу после истечения времени ожидания SET, а не после истечения времени ожидания, так что не выполняется та же задача, что и спящий.

Способ сделать это состоит в том, чтобы разбить вашу функцию на части до и после.

function doStuff()
{
  //do some things
  setTimeout(continueExecution, 10000) //wait ten seconds before continuing
}

function continueExecution()
{
   //finish doing things after the pause
}

Убедитесь, что имена ваших функций по-прежнему точно описывают, что делает каждый компонент (IE GatherInputThenWait и CheckInput, а не funcPart1 и funcPart2)

редактировать

Этот метод позволяет не выполнять выбранные вами строки кода до ПОСЛЕ вашего тайм-аута, в то же время возвращая управление обратно клиентскому ПК, чтобы выполнить все, что еще было поставлено в очередь.

Дальнейшее редактирование

Как указано в комментариях, это абсолютно НЕ РАБОТАЕТ в цикле. Вы могли бы сделать какой-нибудь причудливый (уродливый) взлом, чтобы заставить его работать в цикле, но в целом это просто приведет к катастрофическому спагетти-коду.

176
10.06.2009 18:52:41
Да. Это становится сложным, когда у вас есть цикл или даже вложенный цикл. Вы должны отказаться от своих циклов for и иметь вместо них счетчики.
Nosredna 4.06.2009 15:10:14
Туш. Я имею в виду, это все еще возможно, но в этом случае уродливо и хакерски. Вы также можете использовать некоторые статические переменные логического состояния, но это тоже довольно хакерски.
DevinB 4.06.2009 15:20:42
-1 за это. Опять же, это не отвечает на вопрос. Это больше ответ на вопрос типа «Как выполнить функцию асинхронно», который очень сильно отличается от «Как заблокировать выполнение кода».
Deepak G M 28.01.2013 08:32:55
@Nosredna Нет, вы бы использовали закрытие. Например: function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }and for(var X = 0; X < 3;X++) { foo(X); }- передается значение X foo, которое затем повторно используется под именем, indexкогда foo_continueв конце концов вызывается.
Izkata 13.01.2014 19:34:23
@ Александр Конечно, так и есть, потому что цель setTimeout () - предотвратить блокировку браузера, выполняя код асинхронно. Поместите console.log()внутреннюю часть foo_continue()в версию setTimeout, и вы получите тот же результат.
Izkata 23.03.2015 14:20:00

Если вы используете jQuery, кто-то на самом деле создал плагин «delay», который является не более чем оболочкой для setTimeout:

// Delay Plugin for jQuery
// - http://www.evanbot.com
// - © 2008 Evan Byrne

jQuery.fn.delay = function(time,func){
    this.each(function(){
        setTimeout(func,time);
    });

    return this;
};

Затем вы можете просто использовать его в строке вызовов функций, как и ожидалось:

$('#warning')
.addClass('highlight')
.delay(1000)
.removeClass('highlight');
71
10.06.2009 18:50:32
Это не плохое решение. Сохраняет контекст и цепочность.
Nosredna 10.06.2009 19:00:35
Начиная с jQuery 1.4, .delay()является частью jQuery (хотя семантика отличается от приведенной выше реализации). api.jquery.com/delay
Matt Ball 24.10.2011 13:26:20
Чего не хватало этому вопросу, так это ответа jQuery . Так рада, что мы получили это!
xDaizu 30.08.2016 08:56:31
Если вам нужна задержка между двумя независимыми вызовами, да. Если вам нужны задержки для замедления цикла, нет.
WGroleau 31.05.2018 21:43:33

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

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

// ......................................... // пример1:

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

// .................................... // пример2:

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

// ................. пример3:

<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
10.11.2009 06:06:23
Хорошо, это работает с setTimeput, но трудно увидеть, что происходит. Использование самого setTimeout проще, чем это.
naugtur 9.08.2011 08:19:58

Для конкретного случая, когда требуется разметить набор вызовов, выполняемых циклом, вы можете использовать что-то вроде приведенного ниже кода с прототипом. Без прототипа вы можете заменить функцию задержки на setTimeout.

function itemHandler(item)
{
    alert(item);
}

var itemSet = ['a','b','c'];

// Each call to itemHandler will execute
// 1 second apart
for(var i=0; i<itemSet.length; i++)
{
    var secondsUntilExecution = i;
    itemHandler.delay(secondsUntilExecution, item)
}
5
27.05.2010 19:45:00

Один из сценариев, в котором вам может потребоваться функция sleep () вместо использования setTimeout (), - это если у вас есть функция, реагирующая на щелчок пользователя, который в конечном итоге приведет к открытию нового, т.е. всплывающего окна, и вы инициировали некоторую обработку, которая требует короткого периода завершить до отображения всплывающего окна. Перемещение открытого окна в закрытие означает, что оно обычно блокируется браузером.

6
18.10.2010 19:45:43

(См. Обновленный ответ за 2016 год )

Я думаю, что вполне разумно хотеть выполнить действие, подождать, а затем выполнить другое действие. Если вы привыкли писать на многопоточных языках, у вас, вероятно, есть идея дать выполнение за определенное время, пока ваш поток не проснется.

Проблема здесь заключается в том, что JavaScript является однопоточной моделью, основанной на событиях. Хотя в конкретном случае было бы неплохо подождать всего несколько секунд весь двигатель, в целом это плохая практика. Предположим, я хотел использовать ваши функции при написании своих собственных? Когда я вызывал твой метод, все мои методы зависали. Если JavaScript может каким-то образом сохранить контекст выполнения вашей функции, сохранить его где-нибудь, затем вернуть обратно и продолжить позже, тогда может произойти сон, но это в основном будет потоковым.

Таким образом, вы в значительной степени застряли на том, что предложили другие - вам нужно разбить ваш код на несколько функций.

Тогда ваш вопрос немного ошибочен. Нельзя спать так, как вы хотите, и вы не должны следовать предложенному вами решению.

849
23.05.2017 12:18:28
Это не правильный ответ вообще. Если Javascript не имеет функции сна, это только потому, что ECMAScript не требует этого. Это выбор дизайна органом, ответственным за дизайн Javascript. Можно было бы сделать так, чтобы время выполнения Javascript ожидало заданное количество времени перед запуском следующей строки кода, но было решено не делать этого.
Didier A. 16.08.2013 19:20:56
Сон может быть полностью реализован в JavaScript, но не с точностью в реальном времени. Ведь это система событий. Если асинхронные вызовы завершены, происходит событие. Я не вижу причин, по которым то же самое невозможно сделать, когда выдается sleep (), после чего управление возвращается браузеру до тех пор, пока оно не закончится, возвращая управление вызывающей функции. И да, я также согласен с тем, что иногда сон удобен, особенно когда разработчики ДО того, как вы испортили дизайн так сильно, что у вас нет другого выхода, кроме полного рефакторинга, на который у вас нет времени
Lawrence 14.11.2013 12:40:52
Попробуйте Hypnotic, которая следует этой идее: coolwanglu.github.io/hypnotic/web/demo.html
Tezcat 5.12.2013 10:34:18
Называть JavaScript однопоточным - это миф. Хотя это может быть технически правильно, функционально он действует как многопоточный язык. Имитация fork () тривиально проста, и хотя yield () на самом деле нереализуем, но вы можете приблизиться к нему, используя разделяемую память для блокировки / семафора. Для среднего программиста имеет смысл рассматривать его как многопоточный; техническое название имеет значение только для разработчиков языка.
Benubird 29.01.2015 15:06:15
Я согласен, почему sleep()в JS это невозможно, и что в большинстве случаев есть лучшие способы сделать что-то. Но я все еще рассматриваю способ, которым двигатель связывает все вещи, чтобы быть недостатком дизайна; нет никакой причины, по которой язык не может иметь sleep()функцию, ограниченную конкретным сценарием, страницей или функцией, без того, что движок забивает процессор и замораживает приложение, как маньяк. Это 2015 год, и вы не сможете разбить весь веб-браузер с while(1). У нас есть Flash для таких вещей.
Beejor 12.09.2015 05:10:58

Я также искал решение для сна (не для производственного кода, только для dev / tests) и нашел эту статью:

http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html

... и вот еще одна ссылка с клиентскими решениями: http://www.devcheater.com/

Кроме того, когда вы звоните alert(), ваш код будет также приостановлен, пока отображается предупреждение - нужно найти способ не отображать предупреждение, но получить тот же эффект. :)

46
6.09.2016 07:26:05
Я согласен, многие люди говорят: «Нет, не делайте этого в рабочем коде!» Да, я не хочу. Я хочу сделать это в одноразовом тестовом коде, и в результате я не хочу тратить много времени на создание элегантного решения.
user435779 17.10.2012 15:03:10

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

6
21.06.2011 17:41:26

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

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

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

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

18
8.08.2011 13:05:30
это тот, который работал для меня на настольных браузерах и старом мобильном телефоне. Другие, которые я попробовал, не работали на всех.
Mike 21.01.2020 04:32:26

Прежде всего - setTimeout и setInterval - это то, что следует использовать из-за природы callback-ish в javascript. Если вы хотите использовать sleep()неверный поток управления или архитектуру вашего кода.

Сказав, что я полагаю, я все еще могу помочь с двумя реализациями сна.

  1. притворно синхронно беги с макушки головы

    //a module to do taht //dual-license: MIT or WTF [you can use it anyhow and leave my nickname in a comment if you want to]
    var _=(function(){
     var queue=[];
     var play=function(){
       var go=queue.shift();
         if(go){if(go.a){go.f();play();}else{setTimeout(play,go.t);}}
       }
     return {
       go:function(f){
        queue.push({a:1,f:f});
        },
       sleep:function(t){
        queue.push({a:0,t:t});
        },
       playback:play 
     }
    })();

    [Автоматическое воспроизведение также должно быть возможно]

    //usage
    
    _.go(function(){
    
    //your code
    console.log('first');
    
    });
    
    
    _.sleep(5000);
    
    _.go(function(){
    
    //your code
    console.log('next');
    
    });
    
    //this triggers the simulation
    _.playback();
  2. настоящий синхронный пробег

Однажды я много думал об этом, и единственная идея для настоящего сна в javascript - техническая.

функция сна должна быть синхронным вызовом AJAX с таймаутом, установленным в значение сна. Вот и все, и единственный способ получить настоящийsleep()

4
9.08.2011 08:53:48

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

function()
{
if (!wait_condition)
    {
    setTimeout(arguments.callee, 100, /*comma-separated arguments here*/);
    }
//rest of function
}

Этот код говорит: «Если условие ожидания еще не выполнено, снова вызовите эту функцию с этими аргументами». Я использовал этот метод для передачи одних и тех же аргументов моим обработчикам, что фактически делает этот код незапрашивающим sleep () (который работает только в начале вашей функции).

1
22.02.2012 13:58:16

Я знаю, что это немного старый вопрос, но если (как и я) вы используете Javascript с Rhino, вы можете использовать ...

try
{
  java.lang.Thread.sleep(timeInMilliseconds);
}
catch (e)
{
  /*
   * This will happen if the sleep is woken up - you might want to check
   * if enough time has passed and sleep again if not - depending on how
   * important the sleep time is to you.
   */
}
113
4.11.2011 14:16:06
Это вызов Java?
Ken Sharp 12.03.2015 23:02:16
Это Java, а не Javascript
RousseauAlexandre 31.01.2018 14:39:38
@RousseauAlexandre Неверно. Это JavaScript, использующий Rhino (в то время это мог быть и Nashorn в наши дни)
mjaggard 1.02.2018 20:42:40

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

/**
 * Netscape compatible WaitForDelay function.
 * You can use it as an alternative to Thread.Sleep() in any major programming language
 * that support it while JavaScript it self doesn't have any built-in function to do such a thing.
 * parameters:
 * (Number) delay in millisecond
 */
function nsWaitForDelay(delay) {
    /**
     * Just uncomment this code if you're building an extention for Firefox.
     * Since FF3, we'll have to ask for user permission to execute XPCOM objects.
     */
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

    // Get the current thread.
    var thread = Components.classes["@mozilla.org/thread-manager;1"].getService(Components.interfaces.nsIThreadManager).currentThread;

    // Create an inner property to be used later as a notifier.
    this.delayed = true;

    /* Call JavaScript setTimeout function
      * to execute this.delayed = false
      * after it finish.
      */
    setTimeout("this.delayed = false;", delay);

    /**
     * Keep looping until this.delayed = false
     */
    while (this.delayed) {
        /**
         * This code will not freeze your browser as it's documented in here:
         * https://developer.mozilla.org/en/Code_snippets/Threads#Waiting_for_a_background_task_to_complete
         */
        thread.processNextEvent(true);
    }
}
4
6.08.2018 06:25:51

Метод объекта, который должен использовать «спящий» метод, такой как следующий:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function () {
    this.DoSomething1(arg1);
    sleep(500);
    this.DoSomething2(arg1);
}

Можно почти перевести на:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function (arg1) {
    var self = this;
    self.DoSomething1(arg1);
    setTimeout(function () {
        self.DoSomething2(arg1);
    }, 500);
}

Разница в том, что операция SomeMethod возвращается до выполнения операции DoSomething2. Вызывающий "SomeMethod" не может зависеть от этого. Поскольку метод «Sleep» не существует, я использую более поздний метод и соответствующим образом проектирую свой код.

Надеюсь, это поможет.

1
13.02.2012 22:50:42

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

0
1.11.2012 11:56:48

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

// Basic sleep function based on ms.
// DO NOT USE ON PUBLIC FACING WEBSITES.
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}
30
3.11.2012 02:02:47
Это в основном то же самое, что и ОП.
Andrew Barber 3.11.2012 02:16:23
Чтобы быть более точным, это то, что ОП попросил АЛЬТЕРНАТИВУ.
WGroleau 25.05.2018 20:48:26
Решение не очень хорошее, но в некоторых местах async/awaitоно, к сожалению, не отвечает, и мы вынуждены использовать его в обязательном порядке.
Nabi K.A.Z. 9.06.2018 04:06:31

Добавляю мои два бита. Я нуждался в занятом ожидании для целей тестирования. Я не хотел разбивать код, так как это было бы много работы, поэтому простой for сделал это для меня.

for (var i=0;i<1000000;i++){                    
     //waiting
  }

Я не вижу никаких недостатков в этом, и это помогло мне.

6
20.12.2012 11:57:30
Это может быть скомпилировано.
Viktor Sehr 19.07.2013 20:22:56
Пожалуйста, не делай так. Это блокирующий вызов сна, что означает, что никакой другой javascript не может быть запущен, пока ваш код перегружает поток JS.
Steve Midgley 22.10.2014 04:47:45
@SteveMidgley "никакой другой javascript [не может работать], пока ваш код перегружает поток JS", мне кажется, что именно то, что ОП хочет сделать ¯_ (ツ) _ / ¯
drigoangelo 10.03.2015 22:39:32
Я только что провел несколько тестов, и кажется, что даже пустой цикл заблокирует браузер и процессор (не только JavaScript). И использование forциклов почти всегда выполняется немедленно, независимо от максимального значения для i, и даже со сложным математическим кодом, размещенным внутри. Так что, если вы не ждете всего несколько миллисекунд, кажется, что в JS все равно не будет возможности спать спокойно.
Beejor 14.06.2015 22:03:22
1 миллион слишком велик. Для меня достаточно 10к
Vlad 30.01.2018 14:22:02

Это можно сделать с помощью метода сна Java. Я протестировал его в FF и IE, и он не блокирует компьютер, не проверяет ресурсы и не вызывает бесконечные попадания на сервер. Похоже, чистое решение для меня.

Сначала вы должны загрузить Java на страницу и сделать ее методы доступными. Для этого я сделал это:

<html>
<head>

<script type="text/javascript">

  function load() {
    var appletRef = document.getElementById("app");
    window.java = appletRef.Packages.java;
  } // endfunction

</script>

<body onLoad="load()">

<embed id="app" code="java.applet.Applet" type="application/x-java-applet" MAYSCRIPT="true" width="0" height="0" />

Затем все, что вам нужно сделать, когда вы хотите безболезненную паузу в вашем JS, это:

java.lang.Thread.sleep(xxx)

Где ххх - время в миллисекундах. В моем случае (для обоснования) это было частью выполнения внутреннего заказа в очень маленькой компании, и мне нужно было распечатать счет, который должен был быть загружен с сервера. Я сделал это, загрузив счет (как веб-страницу) в iFrame, а затем распечатал iFrame. Конечно, мне пришлось ждать полной загрузки страницы, прежде чем я смог распечатать, поэтому JS пришлось сделать паузу. Я достиг этого, заставив страницу счета (в iFrame) изменить скрытое поле формы на родительской странице с помощью события onLoad. И код на родительской странице для печати счета-фактуры выглядел следующим образом (несущественные части вырезаны для ясности):

var isReady = eval('document.batchForm.ready');
isReady.value=0;

frames['rpc_frame'].location.href=url;

while (isReady.value==0) {
  java.lang.Thread.sleep(250);
} // endwhile

window.frames['rpc_frame'].focus();
window.frames['rpc_frame'].print();

Таким образом, пользователь нажимает кнопку, скрипт загружает страницу счета, затем ждет, проверяя каждую четверть секунды, чтобы увидеть, закончилась ли загрузка страницы счета, а затем выскакивает диалоговое окно печати, чтобы пользователь мог отправить его на принтер. QED.

6
14.01.2013 01:32:07
Кажется довольно чудовищным, если рассмотреть простую вещь, которую хотел достичь автор.
xaralis 22.01.2013 16:17:29
Это зависит от Java-апплетов, которые устарели.
Vahid Amiri 12.05.2016 13:22:08

Или просто создайте это:

function yourFunction(){

   //do something
   setInterval(myFunc(),1000);
   //do something else

}

function myFunc(){
   return;
}

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

-6
15.02.2013 19:48:37
setInterval будет часто вызывать функцию после завершения таймера
Seeker 19.02.2013 13:21:10
setInterval () создаст форк и будет продолжать вызывать функцию каждые 1000 мс. Но это не остановит выполнение. Это означает, что // do something elseбудет продолжено немедленно.
Mouad Debbar 14.04.2013 20:07:31
и я думаю , что вы хотели сказать: setInterval(myFunc, 1000).
Mouad Debbar 14.04.2013 20:08:10
Здесь я вижу три вопроса: 1. Вы, вероятно, имели в виду setTimeout(myFunc, 1000). 2. Первым аргументом должна быть сама функция [ myFunc], а не результат функции [заданной myFunc()]. 3. ОП явно хотелa real sleep in a middle of a function, not a delay for a piece of code.
Oliver 22.05.2013 13:48:28

Для браузеров, я согласен, что 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

10
17.05.2013 22:53:18

Если вы правы функцию сна, как это

var sleep = function(period, decision, callback){
    var interval = setInterval(function(){
        if (decision()) {
            interval = clearInterval(interval);
            callback();
        }
    }, period);
}

и у вас есть асинхронная функция для вызова несколько раз

var xhr = function(url, callback){
    // make ajax request
    // call callback when request fulfills
}

И вы настраиваете свой проект так:

var ready = false;

function xhr1(){
    xhr(url1, function(){ ready = true;});  
}
function xhr2(){
    xhr(url2, function(){ ready = true; }); 
}
function xhr3(){
    xhr(url3, function(){ ready = true; }); 
}

Тогда вы можете сделать это:

xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
    // do more
});

Вместо бесконечного отступа обратного вызова, подобного этому:

xhr(url1, function(){
    xhr2(url2, function(){
        xhr3(url3, function(){
            // do more
        });
    });
});
4
29.07.2013 21:20:11

Только для debug / dev , я выкладываю это, если это кому-то полезно

Интересные вещи, в Firebug (и, вероятно, других консолях js), ничего не происходит после нажатия enter, только после указанной продолжительности сна (...)

function sleepFor( sleepDuration ){
    var now = new Date().getTime();
    while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

Пример использования:

function sleepThenAct(){ sleepFor(2000); console.log("hello js sleep !"); }
296
10.11.2017 13:41:14
Это не ответ. Это точно так же, как код в вопросе, за исключением чуть короче.
jab 2.06.2015 04:23:09
Ожидание занято, правда? В JS? На секунды? Если я поймаю сайт, делающий это, он будет заблокирован.
mafu 19.08.2016 12:27:53
@mafu Вот почему он говорит only for debug/dev... rolleyes
xDaizu 29.08.2016 10:31:22
НИКОГДА НЕ ДЕЛАЙТЕ ЭТОГО. Это заставит процессор ударить 100% по ядру, которое он выполняет, и заблокирует его.
noego 18.12.2017 10:51:13
Это полезно и, возможно, является ЕДИНСТВЕННЫМ способом для сна в приложении javascript из командной строки, потому что async / await не помогает.
Wheezil 13.01.2018 18:52:47
var waitTillSomethingHappens = function(){  
    if(somethingHappened == 1)  
    {  
        alert('Something Happened get out of sleep');  
    }
    else
    {  
    setTimeout(waitTillSomethingHappens,1000);  
    }  
};
-5
2.08.2013 13:14:03
Это не отвечает на вопрос. Вы не объяснили (или не показали, где определить) свою somethingHappenedфункцию.
RobH 2.08.2013 13:13:13
Если бы это somethingHappenedбыла функция, предупреждение никогда бы не вызывалось, потому что оно никогда не будет равно 1. На самом деле этот пример не должен говорить, == 1потому что он должен быть просто условием заполнения и потому, что вы не должны использовать числа в качестве логических значений, и даже если вы являетесь вами не нужно == 1.
1j01 4.01.2015 04:04:21

Я использую многопоточный HTML5 Worker, который сможет прервать синхронный запрос XMLHttpRequest, указывающий на не отвечающий URL. Это не блокирует браузер.

https://gist.github.com/el-gringo/6990785

0
15.10.2013 12:40:39