Требуется замена JavaScript sleep()

#javascript

#javascript

Вопрос:

Я знаю, что это плохо:

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

EDIT:
function doSomethingQuickly(pixelData) {
    // loads an external image, filling the entire screen
    // overlays $pixelsData over image
}
  

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

 doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);
  

Мой вопрос заключается в том, что, поскольку имитация сна в JS плоха, как я могу добиться того же, используя setTimeout () или другой более приемлемый метод

ПРИМЕЧАНИЕ: это не в веб-браузере

РЕДАКТИРОВАТЬ: Вы можете видеть, что если он запускался 5 раз без режима ожидания, он быстро показывал бы конечное изображение, когда то, что он должен сделать, это 1) показать изображение 2) приостановить на 5 секунд 3) повторить Вы можете видеть, что если он запускался 5 раз без режима ожидания, он быстро показывал бы конечные изображения, когда то, что он должен сделать, это 1) показать изображение 2) приостановить на 5 секунд 3) повторить

Комментарии:

1. Как ваша функция возвращается так быстро, что у нее нет времени для завершения?

2. Ошибка, использовать setTimeout()? Вы сами ответили на свой вопрос. Или я упускаю что-то настолько глубокое, что это почти загадочно?

3. ха-ха @peter здесь нет ничего загадочного, смотрите последнюю правку: комментарий выше. Если вы считаете, что использование setTimeout () не приведет к быстрому удалению первых 4 изображений и отображению только последнего, то я доволен этим. Пиксельные данные — это динамические данные — я надеюсь, что это сработает

4. Если вам нужно дождаться завершения чего-либо, это что-то должно выдать вам обратный вызов, чтобы уведомить вас о завершении. Цикл занятости с жестко запрограммированным ожиданием (или симуляция с setTimeout) слишком хрупок.

Ответ №1:

Как насчет:

 function sleep(ms,callback){
    setTimeout(callback,ms);
}
//basic usage
while (someStoppingcondition){
  sleep(500,doSomethingQuicky);
}
  

если doSomethingQuicky всегда используется одна и та же функция, setInterval достаточно (см. Другие ответы). Убедитесь, что он не будет выполняться вечно, используйте clear[Interval/Timeout] для остановки таймеров.

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

 function firstRunner(arg1,arg2,/* ... argx*/, nextRunner){
   //do things
   //after things are done, run nextRunner
   nextRunner();
}
  

Комментарии:

1. Спасибо, это интересно

2. Зачем вам нужен sleep ? Просто используйте setTimeout

Ответ №2:

JavaScript является однопоточным. Любая серия doSomethingQuicky(); должна выполняться последовательно.

Это если только вы не используете некоторые функции таймера внутри doSomethingQuicky(); . Не зная, что делает эта функция, трудно что-то посоветовать.

Комментарии:

1. Я добавил doSomethingQuickly(). Вы можете видеть, что если бы он запускался 5 раз без режима ожидания, он быстро показал бы окончательные изображения, когда то, что он должен сделать, это 1) показать изображение 2) приостановить на 5 секунд 3) повторить

2. Если изображения загружаются с сервера, JavaScript понятия не имеет, сколько времени это занимает. Вам нужно поместить обработчик «onload» в изображение, затем вызвать следующую функцию загрузки из этого события.

3. Я должен сделать паузу на 5 секунд между загрузками изображения, независимо от того, сколько времени требуется для загрузки (даже если она не загружается полностью)

Ответ №3:

 var interval = setInterval(doSomethingQuickly, 500)

...

clearInterval(interval);
  

Я не знаю, что делает код. JavaScript является однопоточным, поэтому у вас не должно возникнуть никаких проблем. Вы также не должны переходить в спящий режим, поскольку он переводит в спящий режим единственный поток.

Ответ №4:

Использовать sleeps для ожидания возврата функции — это всегда плохая идея. Что, если медленная функция занимает больше времени, чем прогнозировалось? Как насчет проблем с производительностью времени, связанных со временем, проведенным в режиме ожидания?

Вместо этого используйте promises:

 // resolves immediatly to the string 'fast done'
const fast = new Promise(resolve => resolve('fast done'));

// resolves after 1 second to the string 'slow done'
const slow = new Promise(resolve => setTimeout(() => resolve('slow done'), 1000));

// resolves after 1 second to the array ['fast done', 'slow done'], then logs it for demo purposes
Promise.all([fast, slow]).then(console.log);  

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