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

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

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

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

Ответы

Ответ 1

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

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

Запись функции сна просто и делает ее еще более пригодной для использования с JavaScript Promises:

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

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});

Ответ 4

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

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

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 !"); }

Ответ 5

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

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

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

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

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

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

Изменить

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

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

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

Ответ 6

Ради любви к $ 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>

Ответ 7

Я знаю, что это немного старый вопрос, но если (например, я) вы используете 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.
   */
}

Ответ 8

Если вы используете 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');

Ответ 9

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

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

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

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

Ответ 10

Здесь простое решение с использованием синхронного 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);

Ответ 11

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

// 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) {}
}

Ответ 12

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

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

то

sleep(2); // Sleeps for 2 seconds

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

Ответ 13

Во-первых:

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

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

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

setTimeout(alertWorld,1000)

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

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

Ответ 14

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

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

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

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

Ответ 15

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

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

Если вы используете node.js и метеор, вы можете столкнуться с ограничениями использования 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

Ответ 16

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

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

Используется следующим образом:

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

Легко запомнить синтаксис, если вы использовали Promises.

Ответ 17

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

'Javascript is single threaded' недействительный ответ. Например, запуск функции сна внутри рабочего не будет блокировать какой-либо код, запущенный в потоке ui.

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

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

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

Ответ 18

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

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

//......................................... //example 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>

//.................................... //example 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>

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

Ответ 19

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

Ответ 20

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

Ответ 21

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

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

Ответ 22

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

Ответ 23

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

Ответ 24

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

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

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

Ответ 25

Это можно сделать с помощью метода Java sleep. Я тестировал его в 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)

Где 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();

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

Ответ 26

Многие ответы не отвечают на вопрос (и не отвечают), и никто не делает этого...

Здесь мои два цента (или функции):

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

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 been a second");
    after(1000, function(){
        console.log("it been another second");
    });
});

Теперь он легко читается как "после N миллисекунд,..." (или "каждые N миллисекунд,..." )

Ответ 27

В конкретном случае, когда вы хотите освободить набор вызовов, выполняемых циклом, вы можете использовать что-то вроде кода ниже с прототипом. Без прототипа вы можете заменить функцию задержки на 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)
}

Ответ 28

Если вы используете node.js, вы можете взглянуть на волокна - собственное расширение C для узла, своего рода многопоточное моделирование.

Это позволяет вам выполнять настоящий sleep способом, который блокирует выполнение в волокне, но не блокирует основной поток и другие волокна.

Вот свежий пример из собственного readme:

// sleep.js

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

- и результаты:

$ node sleep.js
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)

Ответ 29

Старый вопрос с 2009 года. Теперь в 2015 году возможно новое решение с генераторами, определенными в ECMAscript 2015, а также ES6. Он был одобрен в июне, но раньше он был реализован в Firefox и Chrome. Теперь функция сна может быть сделана не занятой, неблокирующей и вложенной внутренней петлей и подфункций без замораживания браузера. Нужен только чистый JavaScript, нет библиотек или фреймворков.

В приведенной ниже программе показано, как можно сделать sleep() и runSleepyTask(). Функция sleep() - это только оператор yield. Это настолько просто, что на самом деле проще написать оператор yield непосредственно вместо вызова sleep(), но тогда не будет слова сна:-). Результат возвращает значение времени методу next() внутри wakeup() и ждет. Фактическое "спящее" выполняется в wakeup() с использованием старого старого setTimeout(). При обратном вызове метод next() запускает оператор yield для продолжения, а "магия" доходности заключается в том, что все локальные переменные и весь стек вызовов вокруг него все еще остаются нетронутыми.

Функции, которые используют sleep() или yield, должны быть определены как генераторы. Легко сделать, добавив звездочку к ключевому слову function*. Выполнять генератор немного сложнее. При вызове с ключевым словом new генератор возвращает объект, который имеет метод next(), но тело генератора не выполняется (ключевое слово new является необязательным и не имеет значения). Метод next() запускает выполнение тела генератора до тех пор, пока он не встретит yield. Функция-обертка runSleepyTask() запускает пинг-понг: next() ждет yield, а yield ждет next().

Другой способ вызвать генератор - с ключевым словом yield*, здесь он работает как простой вызов функции, но также включает возможность возврата к next().

Об этом свидетельствует пример drawTree(). Он рисует дерево с листьями на вращающейся 3D-сцене. Дерево рисуется как ствол с тремя частями вверху в разных направлениях. Затем каждая часть рисуется как другое, но меньшее дерево, вызывая drawTree() рекурсивно после короткого сна. Очень маленькое дерево рисуется только как лист.

Каждый лист имеет свою собственную жизнь в отдельной задаче, начатой ​​с runSleepyTask(). Он рождается, растет, сидит, исчезает, падает и умирает в growLeaf(). Скорость контролируется с помощью sleep(). Это демонстрирует, как легко выполнять многозадачность.

function* sleep(milliseconds) {yield milliseconds};

function runSleepyTask(task) {
    (function wakeup() {
        var result = task.next();
        if (!result.done) setTimeout(wakeup, result.value);
    })()
}
//////////////// written by Ole Middelboe  /////////////////////////////

pen3D =setup3D();
var taskObject = new drawTree(pen3D.center, 5);
runSleepyTask(taskObject);

function* drawTree(root3D, size) {
    if (size < 2) runSleepyTask(new growLeaf(root3D))
    else {
        pen3D.drawTrunk(root3D, size);
        for (var p of [1, 3, 5]) {
            var part3D = new pen3D.Thing;
            root3D.add(part3D);
            part3D.move(size).turn(p).tilt(1-p/20);
            yield* sleep(50);
            yield* drawTree(part3D, (0.7+p/40)*size);
        }
    }
}

function* growLeaf(stem3D) {
    var leaf3D = pen3D.drawLeaf(stem3D);
    for (var s=0;s++<15;) {yield* sleep(100); leaf3D.scale.multiplyScalar(1.1)}
    yield* sleep( 1000 + 9000*Math.random() );
    for (var c=0;c++<30;) {yield* sleep(200); leaf3D.skin.color.setRGB(c/30, 1-c/40, 0)}
    for (var m=0;m++<90;) {yield* sleep( 50); leaf3D.turn(0.4).tilt(0.3).move(2)}
    leaf3D.visible = false;
}
///////////////////////////////////////////////////////////////////////

function setup3D() {
    var scene, camera, renderer, diretionalLight, pen3D;

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, 
        window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 15, 20);
    renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    directionalLight = new THREE.DirectionalLight(0xffffaa, 0.7);
    directionalLight.position.set(-1, 2, 1);
    scene.add(directionalLight);
    scene.add(new THREE.AmbientLight(0x9999ff));
      
    (function render() {
        requestAnimationFrame(render);
        // renderer.setSize( window.innerWidth, window.innerHeight );
        scene.rotateY(10/60/60);
        renderer.render(scene, camera);
    })();
    
    window.addEventListener(
        'resize',
        function(){
            renderer.setSize( window.innerWidth, window.innerHeight );
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
       }, 
       false
    );
    
    pen3D = {
        drawTrunk: function(root, size) {
            // root.skin = skin(0.5, 0.3, 0.2);
            root.add(new THREE.Mesh(new THREE.CylinderGeometry(size/12, size/10, size, 16), 
                root.skin).translateY(size/2));
            root.add(new THREE.Mesh(new THREE.SphereGeometry(size/12, 16), 
                root.skin).translateY(size));
            return root;
        },
        
        drawLeaf: function(stem) {
            stem.skin.color.setRGB(0, 1, 0);
            stem.add(new THREE.Mesh(new THREE.CylinderGeometry(0, 0.02, 0.6), 
                stem.skin) .rotateX(0.3).translateY(0.3));
            stem.add(new THREE.Mesh(new THREE.CircleGeometry(0.2), 
                stem.skin) .rotateX(0.3).translateY(0.4));
            return stem;
        },
        
        Thing: function() {
            THREE.Object3D.call(this);
            this.skin = new THREE.MeshLambertMaterial({
                color: new THREE.Color(0.5, 0.3, 0.2),
                vertexColors: THREE.FaceColors,
                side: THREE.DoubleSide
            })
        }
    };

    pen3D.Thing.prototype = Object.create(THREE.Object3D.prototype);
    pen3D.Thing.prototype.tilt = pen3D.Thing.prototype.rotateX;
    pen3D.Thing.prototype.turn = pen3D.Thing.prototype.rotateY;
    pen3D.Thing.prototype.move = pen3D.Thing.prototype.translateY;
    
    pen3D.center = new pen3D.Thing;
    scene.add(pen3D.center);
    
    return pen3D;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>

Ответ 30

Начиная с узла 7.6, вы можете комбинировать функцию promisify с модулем utils с setTimeout.

const sleep = require('util').promisify(setTimeout)

Общее использование

async function main() {
    console.time("Slept for")
    await sleep(3000)
    console.timeEnd("Slept for")
}

main()

Вопрос использования

async function asyncGenerator() {
    while (goOn) {
      var fileList = await listFiles(nextPageToken);
      await sleep(3000)
      var parents = await requestParents(fileList);
    }
  }