在JavaScript中同步使用setTimeout

Nat*_*han 49 javascript settimeout

我有以下场景:

setTimeout("alert('this alert is timedout and should be the first');", 5000);
alert("this should be the second one");
Run Code Online (Sandbox Code Playgroud)

我需要在setTimeout执行setTimeout中的代码后执行之后的代码.由于之后的代码setTimeout不是我自己的代码,我不能把它放在setTimeout中调用的函数中...

有没有办法解决?

Dav*_*und 60

代码是否包含在函数中?

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

    // code that you cannot modify?
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以阻止该函数进一步执行,然后再次运行它:

function test(flag) {

    if(!flag) {

        setTimeout(function() {

           alert();
           test(true);

        }, 5000);

        return;

    }

    // code that you cannot modify

}
Run Code Online (Sandbox Code Playgroud)

  • @David Hedlund:这是一个很好的方法,但是当代码不在函数中时,是否有任何方法可以使代码同步? (2认同)

Nat*_*han 38

我上周遇到了类似的功能,这让我想起了这篇文章.基本上我认为@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");
Run Code Online (Sandbox Code Playgroud)

请记住,此代码实际上会占用您的浏览器.希望它能帮助任何人.

  • 实际上,这不会暂停脚本执行,而是在循环完成后执行下一个脚本(调用暂停函数后)。棘手,但从功能上来说它满足了问题的需要。 (2认同)

РАВ*_*АВИ 13

使用 ES6 & promises & async 你可以实现同步运行。

那么代码在做什么呢?

 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();
Run Code Online (Sandbox Code Playgroud)

  • @Chris 你所说的 IE 是什么 ‍♂️? (5认同)

Dar*_*rov 6

把它放在回调中:

setTimeout(function() {
    alert('this alert is timedout and should be the first');
    alert('this should be the second one');
}, 5000);
Run Code Online (Sandbox Code Playgroud)

  • 但他无权访问触发“setTimeout”的代码? (2认同)

And*_*eKR 5

不,因为Javascript中没有延迟功能,除了忙碌的等待(这将锁定浏览器)之外,没有办法做到这一点.

  • `var until = new Date().getTime()+ 3000; while(new Date().getTime()<until){}; 警报('3秒过去');` (6认同)