временная задержка между двумя строками кода в javascript, а не settimeout

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

Я ищу что-то вроде этого псевдокода

write "abc";
delay(500);
write "xyz";

TIA

Изменить: решение jimr в моем другом потоке работало для моей цели, и поэтому Робусто.

Мне просто интересно, почему методы "сна", предоставленные Robusto и ссылкой CMS, не являются предпочтительными. Чем это будет отличаться от метода settimeout, поскольку оба они вводят паузу в коде? (settimeout приостанавливается перед выполнением функции, метод сна приостанавливается перед выполнением следующей строки.)


person Jamex    schedule 15.06.2010    source источник
comment
См. Также: stackoverflow.com/questions/951021/javascript-sleep   -  person Christian C. Salvadó    schedule 16.06.2010
comment
neilmix.com/narrativejs/doc   -  person Ates Goral    schedule 16.06.2010
comment
Причина, по которой это не рекомендуется, уже указана Тобиасом П .: «Выполнение JavaScript блокирует браузер, поэтому метод сна блокирует браузер на 500 мсек. Вы действительно хотите, чтобы ваш браузер не отвечал в течение полсекунды?» Ваш ответ: «settimeout не работает для того, что я пытаюсь сделать». Теперь мой вопрос: что вы пытаетесь сделать? Возможно, есть более эффективный способ решения вашей реальной проблемы, чем использование этого метода delay (и не забудьте использовать @ first-name в ответах на комментарии).   -  person Marcel Korpel    schedule 16.06.2010
comment
Если setTimeout у вас не работает, значит, вам нужно переосмыслить свой код. Использование кода задержки похоже на использование молотка для открытия окна.   -  person epascarello    schedule 16.06.2010
comment
Теперь мы можем использовать aync / await (es6). мой ответ ниже.   -  person Rohith K P    schedule 17.03.2019


Ответы (9)


Следующее является неуклюжим и уродливым, и я бы никогда не сделал это в своем собственном коде, и Я НЕ РЕКОМЕНДУЮ ЭТО ВООБЩЕ, но он показывает, что такое возможно.

// time arg is in milliseconds
function delay(time) {
  var d1 = new Date();
  var d2 = new Date();
  while (d2.valueOf() < d1.valueOf() + time) {
    d2 = new Date();
  }
}
person Robusto    schedule 15.06.2010
comment
lol Я сам писал кастомный сон на jsfiddle, и он действительно ужасно работает :) - person Anurag; 16.06.2010
comment
Это ужасная, ужасная, ужасная идея. Я бы хотел заполнить блок комментариев словом ужасно, но кто-то, вероятно, изменит комментарий. Запись времени на чужой ЦП - это неприлично. По крайней мере, функция должна отказываться от задержки более чем на 1/4 секунды или около того (250 мс). Все еще грубо, но, по крайней мере, довольно кратко. - person Pointy; 16.06.2010
comment
@Pointy: Отсюда мое предисловие некрасиво и неуклюже; Я просто хотел показать, что нечто подобное тому, о чем просил ОП, технически возможно. Я бы никогда не сделал этого в собственном коде. - person Robusto; 16.06.2010
comment
Я не хочу говорить об этом публично, но по независящим от меня причинам мне нужна задержка синхронизации в тестовых спецификациях. Спасибо за это - person basarat; 27.06.2013
comment
И это полезно при отладке сложных ошибок пользовательского интерфейса. Просто чтобы отложить исполнение в определенных местах, чтобы понять, что и когда происходит. - person Murrah; 16.09.2016
comment
Согласитесь с @Murrah - я искал что-то, что заставит отложить выполнение, чтобы убедиться, что я не поддаюсь некоторым ошибкам синхронизации. Это бесполезно для реального кода, но очень полезно для тестирования. Спасибо! :) - person xmnboy; 23.03.2017

Вы можете использовать setTimeout, чтобы почти казалось, что код выполняется на двух строках:

write('abc')
setTimeout(function() {
write('xyz')
},500)
person Joel Coehoorn    schedule 15.06.2010
comment
Спасибо, но settimeout не работает для того, что я пытаюсь сделать. - person Jamex; 16.06.2010

Метод сна недоступен, потому что выполнение JavaScript блокирует браузер, поэтому метод сна блокирует браузер на 500 мсек. Вы действительно хотите, чтобы ваш браузер не отвечал в течение полсекунды?

Используйте setTimeout, как предлагается.

person Tobias P.    schedule 15.06.2010
comment
Спасибо, но settimeout не работает для того, что я пытаюсь сделать. - person Jamex; 16.06.2010
comment
@Jamex да, это так - вам просто нужно настроить то, что вы хотите делать. Сжигание процессорного времени в цикле занятости - в корне плохая идея, особенно когда вы делаете это на чужом компьютере. - person Pointy; 16.06.2010

В JavaScript 1.7, используя yield с async.js, вы можете сделайте следующее:

var yourFunction = _(function () {
    write("abc");
    yield to.sleep(.500);
    write("xyz");
});
person Eli Grey    schedule 15.06.2010
comment
Спасибо за информацию. Кажется, что урожайность еще многим неизвестна. - person Jamex; 16.06.2010
comment
Очень чистый способ сделать это. - person Jean Jimenez; 10.03.2019

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

Вы случайно не манипулируете DOM между этими двумя командами записи? Если да, то он просто не будет работать (с точки зрения конечного пользователя), хотя узлы DOM будут построены / обновлены в памяти, отображение не будет обновляться, поскольку эта часть не синхронна. Процессор заблокирован в этом цикле, и оба обновления DOM обновятся на экране, когда этот цикл завершится. См. Этот пример.

В идеале вы должны увидеть на экране «Hello», а через 5 секунд - «World». Однако в Chrome, Safari и Firefox вы увидите как «Hello», так и «World» по истечении 5 секунд. Журналы консоли доказывают, что узел DOM построен в памяти, но не обновляется на экране до конца, как вы сами видите.

person Anurag    schedule 15.06.2010
comment
Я пытался сделать document.onclick и получить идентификатор любого элемента, на который я щелкнул. Проблема заключалась в том, что по истечении установленного времени событие щелчка было потеряно. Другой пользователь (jimr) был достаточно любезен, чтобы написать короткую программу, которая сохраняет для меня событие. Я недостаточно знаю синтаксис JS, чтобы понимать хороший код. Я пишу только псевдологические коды и пытаюсь найти правильный синтаксис, но трудно найти ответы в Google, если я не знаю ключевых слов / идей. Спасибо. - person Jamex; 16.06.2010
comment
@Jamex - Я думаю, что если вы обновите вопрос, добавив в него детали из вашего комментария выше, вы получите гораздо более полезные и лучшие ответы, как только пользователи лучше поймут проблему. - person Anurag; 16.06.2010
comment
@Jamex (и Anurag) - я думаю, что на исходный вопрос уже дан ответ в другом вопросе, который вы упомянули (хотя и не идеально). - person Marcel Korpel; 16.06.2010

Насколько мне известно, setTimeout() - единственный способ сделать это.

function write(out) {
  alert(out);
}

// ...

write('abc');
setTimeout(function() { write('xyz')}, 500);
person Hooray Im Helping    schedule 15.06.2010
comment
Спасибо, но settimeout не работает для того, что я пытаюсь сделать. - person Jamex; 16.06.2010

ES6 представил async / await, который можно раньше была реальная задержка. Я ответил на это в другом сообщении, просто обновляю здесь

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

    async function delay(delayInms) {
      return new Promise(resolve  => {
        setTimeout(() => {
          resolve(2);
        }, delayInms);
      });
    }
    async function sample() {
      console.log('a');
      console.log('waiting...')
      let delayres = await delay(3000);
      console.log('b');
    }
    sample();

person Rohith K P    schedule 17.03.2019

Я скучаю по этому и по javascript, так как энтузиаст java SE и EE, не имеющий моего sleep(), разочаровывает меня в JavaScript, я сделал таймер и надеюсь, что он может быть вам полезен, он использует jQuery, и это довольно просто, вы можете отменить спроектируйте его и создайте что-то, что соответствует вашим потребностям:

function timer(object, time) {
  $(object).attr({
    'onclick': ''
  });
  if (time < 0) {
    $(object).attr({
      'onclick': "timer('#clock', 6000);"
    });
    return;
  }
  $(object).animate({
    opacity: 1
  }, 1, function() {
    $(object).empty();
    $(object).append(time + 'ms');
    time--;
    timer(object, time);
  });
}
#clock {
  width: 65px;
  height: 20px;
  border: 1px solid #F00;
  text-align: center;
  line-height: 20px;
  background-color: #000;
  color: #FFF;
  font-weight: 900;
}
<!DOCTYPE html>
<html>

<head>
  <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
  <title>HTML5, CSS3 and JavaScript demo</title>
</head>

<body>
  <div id="clock" onclick="timer('#clock',6000);">--s</div>
</body>

</html>

person Kyle    schedule 15.12.2015

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

const add2SecondsDelay = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('added 2 seconds delay);
    }, 20000);
  });
}

async function asyncFunctionCall() {

  console.log('abc'); // ------> first step
  const result = await add2SecondsDelay();
  console.log("xyz"); // ------> second step will execute after 2 seconds

}

asyncFunctionCall();
person p.durga shankar    schedule 09.01.2020