一.定時器 1. JS存在兩種定時器 setTimeout() 延遲定時器 setInterval() 迴圈定時器(“間隔器”) 定時器中的函數掛載在window對象,內部的this ——> window setTimerout(function(){ console.log('wuwei') }, ...
一.定時器
1. JS存在兩種定時器
setTimeout() 延遲定時器
setInterval() 迴圈定時器(“間隔器”)
定時器中的函數掛載在window對象,內部的this ——> window
setTimerout(function(){
console.log('wuwei')
},1000); // 一秒後列印wuwei
setInterval(function(){
console.log('wuwei')
},1000); // 每隔一秒就列印wuwei,如果不清楚或關閉頁面,將會無限迴圈下去
2. 清除定時器
在每次使用定時器時,都必須清除定時器
如何清除定時器呢,每一個定時器開啟後都會返回一個對應的id,說白了就是js裡面的第幾個定時器,通過這個id就可以清除定時器,清除定時器用如下的方法
clearTimeout(timer) ==> 用於清除setTimeout
clearInterval(timer) ==> 用於清除setInterval
// 在開啟定時器的同時定義一個變數接受定時器返回的id,用於清除定時器
// 清除setTimeout
var timer = setTimeout(function(){
console.log('wuwei')
},2000)
clearTimerout(timer);
// 清除setInterval
var timer2 = setInterval(function(){
console.log('wuwei')
},2000)
clearTimerout(timer2);
3.關於定時器函數的參數
定時器接受多個參數
第一個參數是執行的函數,必須傳遞,不傳沒什麼意義,不傳報錯
第二個為定時器執行的毫秒數,可以不傳,不會報錯,感覺起來是立即執行,其實不是
第三個之後的所有參數,都將是第一個參數函數執行的實參
// 省略第二個參數會立即執行
setTimeout(function(){
console.log('無為')
})
// 第三個以後的參數是第一個參數函數執行時的實參
setTimeout(function(,a,b){
console.log(a,b)
},2000,10,20);
HTML5標準規定了setTimeout()的第二個參數的最小值(最短間隔),不得低於4毫秒,如果低於這個值,就會自動增加。在此之前,老版本的瀏覽器都將最短間隔設為10毫秒。不同的瀏覽器實現不同
4. 關於定時器的第一個參數
定時器的第一個參數可以是多種形式
4.1 匿名函數
setTimeout(function(){
console.log('無為')
},2000)
4.2 有名函數
setTimeout(function haha(){
console.log('無為')
},2000)
4.3 有名函數的函數名
function haha(){
console.log('wuwei');
}
setTimeout(haha,2000)
4.4 能被當成js語句執行的字元串
setTimeout('console.log("hahah")',2000)
二.JS的單線程
1. 什麼是單線程
同時只能執行一個任務,如果後面有任務,需要等到當前任務執行完畢,才能執行後面的任務
for(var i = 0; i< 10000;i++){
console.log(1);
}
console.log(2);
js的是單線程的也就是說上面的代碼,無論for迴圈多麼耗時,都必須先執行完,在列印2,這就會造成線程阻塞的問題
2. 什麼叫線程阻塞
前面的任務死迴圈或者耗時過長導致後面代碼不能被執行,這種情況叫做線程阻塞,
這樣就會出現問題,所以對於像事件,定時器,ajax請求這種非常耗時的程式.瀏覽器就會開闢其他的線程來處理,所以這些程式我們叫他非同步程式
瀏覽器有三個常駐線程,JS引擎線程,界面的渲染線程,以及瀏覽器事件觸發線程,還有一些執行完就終止的線程,比如HTTP請求線程
在看一個例子:
for(var i = 0; i< 5; i++){
setTimeout(function(){
console.log(i)
},1000)
}
// 列印幾
3. 同步任務和非同步任務
js的單線程意味著所有的任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。
所以JS的任務隊列分成兩種,同步任務,和非同步任務
同步任務:在JS主線程排隊執行的任務
=> 形成執行棧
非同步任務:不進入主線程進入”任務隊列”的任務
=> 形成任務隊列
非同步任務只有任務隊列通知主線程,某個非同步任務可以執行了,該任務才會進入主線程執行
所以下麵的程式定時器會後執行
setTimeout(function(){
console.log(1)
},0)
for(var i = 0; i< 10000;i++){
console.log(2)
}
定時器會等待for迴圈執行完畢後在執行.
4. JS代碼的執行順序
先執行主程式的任務,當主程式的所有任務都執行結束,再把任務隊列中的任務放到主程式中執行
所有同步任務都在主線程上執行,形成一個執行棧。
主線程之外,還存在一個”任務隊列”。只要非同步任務有了運行結果,就在”任務隊列”之中放置一個事件。
一旦”執行棧”中的所有同步任務執行完畢,系統就會讀取”任務隊列”,看看裡面有哪些事件。那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。
主線程不斷重覆上面的第三步。
5. JS中的非同步任務有哪些???
定時器
事件
Ajax