используя setTimeout синхронно в JavaScript - PullRequest
48 голосов
/ 08 ноября 2010

У меня следующий сценарий:

setTimeout("alert('this alert is timedout and should be the first');", 5000);
alert("this should be the second one");

Мне нужен код после выполнения setTimeout после выполнения кода в setTimeout.Поскольку код, следующий за setTimeout, не является моим собственным, я не могу поместить его в функцию, вызываемую в setTimeout ...

Есть ли способ обойти это?

Ответы [ 8 ]

61 голосов
/ 08 ноября 2010

Код содержится в функции?

function test() {
    setTimeout(...);     

    // code that you cannot modify?
}

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

function test(flag) {

    if(!flag) {

        setTimeout(function() {

           alert();
           test(true);

        }, 5000);

        return;

    }

    // code that you cannot modify

}
35 голосов
/ 10 ноября 2014

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

function pause(milliseconds) {
	var dt = new Date();
	while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}

document.write("first statement");
alert("first statement");

pause(3000);

document.write("<br />3 seconds");
alert("paused for 3 seconds");

Имейте в виду, что этот код поддерживает ваш браузер. Надеюсь, это кому-нибудь поможет.

6 голосов
/ 08 ноября 2010

Просто поместите его в обратный вызов:

setTimeout(function() {
    alert('this alert is timedout and should be the first');
    alert('this should be the second one');
}, 5000);
5 голосов
/ 08 ноября 2010

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

4 голосов
/ 03 января 2018

ES6 (занят в ожидании)

const delay = (ms) => {
  const startPoint = new Date().getTime()
  while (new Date().getTime() - startPoint <= ms) {/* wait */}
}

использование:

delay(1000)
2 голосов
/ 08 ноября 2010
setTimeout(function() {
  yourCode();    // alert('this alert is timedout and should be the first');
  otherCode();   // alert("this should be the second one");
}, 5000);
1 голос
/ 15 мая 2018

Используя ES6, обещания и асинхронность, вы можете добиться синхронного запуска.

Так, что делает код?

 1. Calls setTimeOut 1st inside of demo then put it into the webApi Stack
 2. Creates a promise from the sleep function using the setTimeout, then resolves after the timeout has been completed;
 3. By then, the first setTimeout will reach its timer and execute from webApi stack. 
 4. Then following, the remaining alert will show up.


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

async function demo() {
  setTimeout("alert('this alert is timedout and should be the first');", 5000);
  await sleep(5000);
  alert('this should be the second one');
}
demo();
0 голосов
/ 08 ноября 2010

Вы можете попытаться заменить window.setTimeout своей собственной функцией, например

window.setTimeout = function(func, timeout) {
    func();
}

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

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

...