0%

如何在JavaScript中延迟1S

如何在JavaScript中延迟1S

在JS中,需要进行延迟的话,通常的做法是使用**setTimeout,更好的方式是使用Promise**

有很多方法可以让JavaScript等待1秒。有些比其他更好,有些只能在特定情况下使用。

1. 使用setTimeout

如:

1
2
3
4
5
6
console.log("Executed now");

// 1 second delay
setTimeout(function(){
console.log("Executed after 1 second");
}, 1000);

需要特别注意的是,setTimeout是在异步运行的,延迟并不会阻止正常程序的流程,如

1
2
3
4
5
6
7
8
9
console.log("Executed now");

// 1 second delay
setTimeout(function(){
console.log("Executed after 1 second");
}, 1000);

// Notice this!
console.log("Executed before the delay, but after the 1st console.log");

输出:

1
2
3
Executed now
Executed before the delay, but after the 1st console.log
Executed after 1 second

如果你想在同一个延迟函数中不断添加延迟,我们很容易遇到所谓的回调地狱。

2. 使用Promise

如果我们把setTimeout函数和promises函数结合起来,我们就可以创建一个更易读的代码,并把整个代码放在同一个(async)函数中。

与我们之前解释过的setTimeout方法相比,它的主要优点是我们可以重用延迟函数。使我们的代码更加干净和简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function delay(milliseconds){
return new Promise(resolve => {
setTimeout(resolve, milliseconds);
});
}

async function init(){
console.log("Executed now");

await delay(1000);

console.log("Executed after 1 second wait");

await delay(1000);

console.log("Executed after 2 seconds wait");
}

init();

console.log("Executed after the 1st log and before the 2 delays");

输出

1
2
3
4
> Executed now
> Executed after the 1st log and before the 2 delays
> Executed after 1 second wait
> Executed after 2 seconds wait

3. 使用等待循环(loop)

这是唯一完全中断用户流程并强制 JavaScript 进行同步暂停的方法。

这并不是完美的解决方案,我认为这可能是不可取的。JavaScript 是一种异步语言,我们应该利用它,而不是使用巧妙的解决方案使我们的代码变成同步的。

1
2
3
4
5
6
7
8
9
10
11
var wait = (ms) => {
const start = Date.now();
let now = start;
while (now - start < ms) {
now = Date.now();
}
}

console.log("Executed now");
wait(1000);
console.log("Executed after 1 second");

我们基本上使用 Date 函数检查当前时间,并创建一个 do ... while 循环,只有在我们开始循环后超过1000毫秒才会退出。

最大的问题就是?我们基本上是通过运行一个“无意义”的循环并比较日期来让我们的计算机/浏览器忙碌,只是为了延迟。

如果我们等待的时间不是1秒,那么我们的浏览器很可能会崩溃,或者我们的页面停止像平常那样响应。即使我们使用1秒的数值,事情也可能不会总是按我们的期望工作。DOM 渲染发生在 JavaScript 函数栈已清空并且浏览器可以接受新事件之后。

并且为了证明这一点,请看以下示例,在这个示例中, console.log 在1秒后被触发(正如我们所期望的那样),但是两个DOM写入操作同时发生:

上面代码输出

1
2
> Executed now
> Executed after 1 second

这不是一个好的解决方案,如果可能的话,尽量避免采用这个解决方案,而是选择前两种方案。