日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

setTimeout、setInterval、promise、async/await的顺序详解(多种情况,非常详细~)

發布時間:2023/11/27 生活经验 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 setTimeout、setInterval、promise、async/await的顺序详解(多种情况,非常详细~) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文很長,列舉的情況很多。
在閱讀本文之前,如果您有充足的時間,請新建一個項目與本文一同實踐。
每段代碼都有對應的解釋,但是自己動手嘗試印象才會更深哦~

setInterval:表示多久執行一次,需要clearInterval(timer)來讓它停下。要是不clearInterval(timer),它就會越來越快!
setTimeout:表示過了多久之后執行,只會執行一次!
比如這段代碼,實現的是每秒都在console里輸出現在的時間,5秒后停止。
上代碼

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Test</title></head><body><div id="root"></div><script>let timertimer = setInterval(function () {console.log(new Date())}, 1000)setTimeout(function () {clearInterval(timer)}, 5000)</script></body>
</html>

運行結果:

如果setTimeout設置時間為0呢?
修改一下代碼:

<script>let timertimer = setInterval(function () {console.log(new Date())}, 1000)setTimeout(function () {clearInterval(timer)}, 5000)setTimeout(function () {console.log('hello')}, 0)</script>

運行結果:

加上promise

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Test</title></head><body><div id="root"></div><script>console.log('1')setTimeout(() => {console.log('2')}, 0)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')}, 0)console.log('4')})promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script></body>
</html>

看下結果:

這一段完全沒有調用到。

promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})

為啥呢,因為沒有resolve()
加上resolve()之后呢?

<script>console.log('1')setTimeout(() => {console.log('2')}, 0)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')setTimeout(() => {resolve()}, 0)}, 0)console.log('4')})promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>

那是不是什么時候resolve()就什么時候輸出呢?
答案是:不是
把“2”換到下面來試一下:

<script>console.log('1')let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')setTimeout(() => {resolve()}, 0)}, 0)console.log('4')})setTimeout(() => {console.log('2')}, 0)promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>


可見3和2的位置確實變了,但是promise部分,就是5和6,仍然是最后出現。

那有多個setTimeout會怎樣呢?我們加一個“2.5”試一下:

<script>console.log('1')setTimeout(() => {console.log('2.5')}, 0)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')setTimeout(() => {resolve()}, 0)}, 0)console.log('4')})setTimeout(() => {console.log('2')}, 0)promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>

輸出結果是:

可見是從上至下的啊~

如果讓resolve()和console.log(‘3’)擺在一起呢?

<script>console.log('1')setTimeout(() => {console.log('2.5')}, 0)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')resolve()}, 0)console.log('4')})setTimeout(() => {console.log('2')}, 0)promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>

執行結果:

可見,在setTimeout里套的setTimeout會被最后執行。

如果改一下執行時間呢?把2.5輸出的時間改為運行0.1s之后?

<script>console.log('1')setTimeout(() => {console.log('2.5')}, 100)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')setTimeout(() => {resolve()}, 0)}, 0)console.log('4')})setTimeout(() => {console.log('2')}, 0)promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>

執行結果:

它會出現在最后!

那如果resolve()執行時間延后呢?

<script>console.log('1')let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')resolve()}, 100)console.log('4')})setTimeout(() => {console.log('2')}, 0)promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>

運行結果:

該先執行的還是先執行了啊~

加上async/await會怎樣?神奇的事發生了!

<script>console.log('1')setTimeout(() => {console.log('2.5')}, 0)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')resolve()}, 0)console.log('4')})setTimeout(() => {console.log('2')}, 0)async function async1() {console.log('async1 start')await async2()console.log('async1 end')}async function async2() {console.log('async2')}console.log('script start')async1()console.log('script end')promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>

輸出結果是:

async 函數返回一個 Promise 對象,當函數執行的時候,一旦遇到 await 就會先返回,等到觸發的異步操作完成,再執行函數體內后面的語句。可以理解為,是讓出了線程,跳出了 async 函數體。

setTimeout會在async/await之后再執行。但promise的內容會在async/await之前執行。

混亂起來了:把setTimeout塞進async/await中會怎么樣?

<script>console.log('1')setTimeout(() => {console.log('2.5')}, 0)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')resolve()}, 0)console.log('4')})setTimeout(() => {console.log('2')}, 0)async function async1() {console.log('async1 start')setTimeout(() => {console.log('async1 start setTimeout')}, 0)await async2()console.log('async1 end')setTimeout(() => {console.log('async1 end setTimeout')}, 0)}async function async2() {console.log('async2')setTimeout(() => {console.log('async2 setTimeout')}, 0)setTimeout(() => {console.log('async2 setTimeout after')}, 100)}console.log('script start')async1()console.log('script end')promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script>

輸出結果:(看仔細了哦)

所以塞在async/await中的setTimeout會被最后執行。

終極混亂:

let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')setTimeout(() => {resolve()}, 0)}, 0)console.log('4')})

在Promise里的setTimeout里的setTimeout里的resolve()是什么時候執行的?
完整代碼:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Test</title></head><body><div id="root"></div><script>console.log('1')setTimeout(() => {console.log('2.5')}, 0)let promise = new Promise((resolve, reject) => {setTimeout(() => {console.log('3')setTimeout(() => {resolve()}, 0)}, 0)console.log('4')})setTimeout(() => {console.log('2')}, 0)async function async1() {console.log('async1 start')setTimeout(() => {console.log('async1 start setTimeout')}, 0)await async2()console.log('async1 end')setTimeout(() => {console.log('async1 end setTimeout')}, 0)}async function async2() {console.log('async2')setTimeout(() => {console.log('async2 setTimeout')}, 0)setTimeout(() => {console.log('async2 setTimeout after')}, 100)}console.log('script start')async1()console.log('script end')promise.then((res) => {console.log('5')}).then((res) => {console.log('6')})console.log('7')</script></body>
</html>

輸出結果:

啊,原來是這樣,這一部分會被最后執行!
(作者已經要陷入混亂中了…)

休息一下…接著做~
setTimeout的層疊實驗:

<script>setTimeout(() => {console.log('1')setTimeout(() => {console.log('1.2.before3')setTimeout(() => {console.log('1.3.1')}, 0)setTimeout(() => {console.log('1.3.2')}, 0)}, 0)setTimeout(() => {console.log('1.2.after3')}, 0)}, 0)setTimeout(() => {console.log('2')setTimeout(() => {console.log('2.2.1')}, 0)setTimeout(() => {console.log('2.2.2')}, 0)}, 0)setTimeout(() => {console.log('3')}, 0)</script>

輸出結果:

事實證明,setTimeout是一層一層來的,理解好“第幾批”很重要。

可以自己嘗試一下,這個如金字塔一樣的結構,先搭好第一層地基,才會向上搭建這種思想。

至此你已經看完了所有的內容,感謝觀看,實操大于理解,還是建議讀者新建一個項目自己動手嘗試各種情況,還有更多嵌套情況本文沒有列出,如有勤奮的同學列舉,歡迎討論~


補充:

setTimeout并不是準時的原因

  • 因為 JavaScript 是一個單線程序的解釋器,因此一定時間內只能執行一段代碼。
  • 為了控制要執行的代碼,就有一個 JavaScript 任務隊列。
  • 這些任務會按照將它們添加到隊列的順序執行。
  • setTimeout() 的第二個參數告訴 JavaScript 再過多長時間把當前任務添加到隊列中。如果隊列是空的,那么添加的代碼會立即執行;如果隊列不是空的,那么它就要等前面的代碼執行完了以后再執行

總結

以上是生活随笔為你收集整理的setTimeout、setInterval、promise、async/await的顺序详解(多种情况,非常详细~)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。