js中的同步中異步執行代碼


for(var i=0;i<10;i++){
  setTimeout(function(){
    console.log(i)
  },0)
}
//結果是輸出10次10;

一:執行機制,同步先執行-異步-最后回調再執行
for循環是同步代碼,而setTimeout中的是異步代碼。

JS中既有同步又有異步的情況下,先從上到下執行同步代碼,碰到異步的代碼會將其插入到任務隊列當中等待。

而setTimeout是延時,也就是說碰到setTimeout這個異步的代碼塊會根據它里面的第二個參數:延時時間來將代碼插入到任務隊列當中。

比如上面這段代碼中,第二個參數延時時間是0,也就是說執行到它的時候會在0ms之后將它插入到任務隊列當中。同步代碼都執行完成之后,那么JS引擎就空閑了,這個時候就輪到任務隊列中的異步代碼依次加載了。

二:作用域鏈

執行settimeout時輸出i,現在當前執行函數中查找i,查找失敗,找到全局作用域i,此時for循環已經執行完畢i=10;

解決辦法-----------------------------立即執行函數,返回當前i

for(var i=0;i<10;i++){

function(a){

  setTimeout(function(){
    console.log(i)
  },0)}(i)

  
}

輸出0 1 2 3 4 5 6 7 8 9 

解決辦法-----------------------------let塊

for(let i=0;i<10;i++){
  setTimeout(function(){
    console.log(i)
  },0)
}

let  i  的是區塊變量,每個i只能存活到大括號結束,並不會把后面的for循環的  i  值賦給前面的setTimeout中的i;

  i被綁定到循環體的每一次迭代中,確保上一次迭代結束的值重新被賦值。

  setTimeout里面的function()屬於一個新的域,

  通過 var 定義的變量是無法傳入到這個函數執行域中的,

  通過 let 來聲明塊變量,這時候變量就能作用於這個塊,所以 function就能使用 i 這個變量了;

var i  則是局部變量,這個 i 的生命周期不受for循環的大括號限制;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM