Event Loop(JS的執行機制)
阿新 • • 發佈:2019-02-04
JS引擎的執行機制:(單執行緒和event Loop的執行機制)
參考:
https://segmentfault.com/a/1190000012806637
http://www.ruanyifeng.com/blog/2013/10/event_loop.html
注意:
Worker API可以實現多執行緒,但是JavaScript本身始終是單執行緒的
1.什麼是even Loop的執行機制
簡單的來說,就是在程式中,設定兩個執行緒:
一個執行緒,負責程式本身的執行,稱為主執行緒
一個執行緒負責主執行緒與其他執行緒的操作(主要是各種IO操作),稱為event Loop執行緒(也叫訊息執行緒)
執行原理:
1.主程式遇到I/O的時候,交給event Loop執行(自己則繼續往後面執行)
2.等到Event LOop執行緒執行完畢之後,返回給主執行緒
3.主執行緒觸發,相應的回撥操作
4.執行完畢
結論:
這樣,就解決了單執行緒的問題
這種執行方式,叫做非同步模式或非阻塞模式(node JS 也是這樣的)
2.JS是單執行緒的歷史原因
為了簡單
佇列,併發,程序和執行緒--在瀏覽器中(怎麼簡單,怎麼來)
3.為啥要使用非同步:
設計到了JS的執行順序
自上而下的 (有一段程式碼太大,後面就會卡死)
這個就叫做阻塞,於是就有了非同步的解決方案.
4.非同步的執行案例:
程式碼:
<script>
console.log('開始的console');
setTimeout(function () {
console.log('定時器')
},0);
console.log('結尾的console');
</script>
對於上面案例的分析:
開始的console-->結尾的console--->定時器
再看一眼執行的順序:
1.判斷程式碼是同步的還是非同步的
同步的,就進入主執行緒
非同步的,就進入event tablt
2.非同步的任務在event table 裡面註冊函式,當滿足觸發條件的時候進入event queque(就是事件佇列)
3.當主執行緒空閒的時候,就去event queque裡面檢視是否有可執行的非同步任務
如果,有 就推入到主執行緒裡面
於是,上面的就可以解釋了
setTimeout() 是一個非同步的任務(空閒的時間才會執行他)
===================================================================
另一個案例:
程式碼:
<script>
setTimeout(function () {
console.log('定時器開始了');
})
new Promise(function (resolve) {
console.log('執行for迴圈之前');
for(var i=0;i<1000;i++){
i==99&&resolve();
}
}).then(function () {
console.log('執行了then函數了')
})
console.log('程式碼執行結束了');
</script>
在此之前,我們需要了解一下ES6的一些語法
ES6(碰到一個,學一個)
參考:
http://es6.ruanyifeng.com/#docs/promise
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
關於promise(承諾)
1.他是一個容器(物件方式的容器)
2.容器裡面存放的是某個非同步操作(未來才會結束的事件)
3.容器裡面的內容有什麼特點呢??
1.物件的狀態不受外部的影響
那他有哪幾種會狀態呢??
pending(進行中)、fulfilled(已成功)和rejected(已失敗)
只有非同步操作的結果,可以改變狀態
2.一旦狀態改變就不會再變,任何時候都是這個結果
什麼是狀態改變:
狀態改變,只有兩種可能:從pending變為fulfilled和從pending變為rejected
為了方便,我們把
resolved(已定型)統一隻指fulfilled
4.promise的語法結構:
Promise()建構函式,建立promise物件
程式碼:
new Promise(function(resolve, reject){ //必須寫上回調函式,否則會報錯的
//引數,resolve和reject ,由 JavaScript 引擎提供,不用自己部署。
}).then(function(value){
//成功的返回值
靜態方法 Promise.resolve返回一個promise物件,這個promise物件是被解析後(resolved)的
},function(error){
//失敗的返回值
})
關於這兩個引數:(貌似都是返回一個物件啊)
1.Promise.resolve()方法
靜態方法 Promise.resolve返回一個promise物件,這個promise物件是被解析後(resolved)的
語法:
Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);
2.Promise.reject(reason)方法返回一個用reason拒絕的Promise\
擴充套件結束,我們來分析這個案例:
執行結果:
執行for迴圈之前-->程式碼執行結束了--->執行了then函數了--->定時器開始了
結構分析:
1.由上到下執行
setTimeout() 放在全域性的非同步執行佇列中(巨集任務)
2.建立promise物件
回撥函式立即執行,列印執行for迴圈之前
then 是非同步的,存在當前的非同步執行佇列中(微任務)
3.全域性
程式碼執行結束了
4.返回到那個內部的非同步 Event Loop裡面執行
執行then函式
5,執行全域性的非同步佇列中的函式
執行完主程式之後
先看看微任務有未執行的嗎,如果有,就先執行他-=--這不是開小灶嗎
之後執行紅任務
疑惑:
就兩個執行緒
這個多了一個,算是巢狀嗎????
還有一個坑:
程式碼:
setTimeout(
function(){
console.log('執行了')
},3000 )
其實,不是3s之後執行
而是,3s之後,被推入Event Loop執行佇列中
主程式有空閒,就來執行該程式
執行的條件
所以只有滿足 (1)3秒後 (2)主執行緒空閒,同時滿足時,才會3秒後執行該函式
參考:
https://segmentfault.com/a/1190000012806637
http://www.ruanyifeng.com/blog/2013/10/event_loop.html
注意:
Worker API可以實現多執行緒,但是JavaScript本身始終是單執行緒的
1.什麼是even Loop的執行機制
簡單的來說,就是在程式中,設定兩個執行緒:
一個執行緒,負責程式本身的執行,稱為主執行緒
一個執行緒負責主執行緒與其他執行緒的操作(主要是各種IO操作),稱為event Loop執行緒(也叫訊息執行緒)
執行原理:
1.主程式遇到I/O的時候,交給event Loop執行(自己則繼續往後面執行)
2.等到Event LOop執行緒執行完畢之後,返回給主執行緒
3.主執行緒觸發,相應的回撥操作
4.執行完畢
結論:
這樣,就解決了單執行緒的問題
這種執行方式,叫做非同步模式或非阻塞模式(node JS 也是這樣的)
2.JS是單執行緒的歷史原因
為了簡單
佇列,併發,程序和執行緒--在瀏覽器中(怎麼簡單,怎麼來)
3.為啥要使用非同步:
設計到了JS的執行順序
自上而下的 (有一段程式碼太大,後面就會卡死)
這個就叫做阻塞,於是就有了非同步的解決方案.
4.非同步的執行案例:
程式碼:
<script>
console.log('開始的console');
setTimeout(function () {
console.log('定時器')
},0);
console.log('結尾的console');
</script>
對於上面案例的分析:
開始的console-->結尾的console--->定時器
再看一眼執行的順序:
1.判斷程式碼是同步的還是非同步的
同步的,就進入主執行緒
非同步的,就進入event tablt
2.非同步的任務在event table 裡面註冊函式,當滿足觸發條件的時候進入event queque(就是事件佇列)
3.當主執行緒空閒的時候,就去event queque裡面檢視是否有可執行的非同步任務
如果,有 就推入到主執行緒裡面
於是,上面的就可以解釋了
setTimeout() 是一個非同步的任務(空閒的時間才會執行他)
===================================================================
另一個案例:
程式碼:
<script>
setTimeout(function () {
console.log('定時器開始了');
})
new Promise(function (resolve) {
console.log('執行for迴圈之前');
for(var i=0;i<1000;i++){
i==99&&resolve();
}
}).then(function () {
console.log('執行了then函數了')
})
console.log('程式碼執行結束了');
</script>
在此之前,我們需要了解一下ES6的一些語法
ES6(碰到一個,學一個)
參考:
http://es6.ruanyifeng.com/#docs/promise
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
關於promise(承諾)
1.他是一個容器(物件方式的容器)
2.容器裡面存放的是某個非同步操作(未來才會結束的事件)
3.容器裡面的內容有什麼特點呢??
1.物件的狀態不受外部的影響
那他有哪幾種會狀態呢??
pending(進行中)、fulfilled(已成功)和rejected(已失敗)
只有非同步操作的結果,可以改變狀態
2.一旦狀態改變就不會再變,任何時候都是這個結果
什麼是狀態改變:
狀態改變,只有兩種可能:從pending變為fulfilled和從pending變為rejected
為了方便,我們把
resolved(已定型)統一隻指fulfilled
4.promise的語法結構:
Promise()建構函式,建立promise物件
程式碼:
new Promise(function(resolve, reject){ //必須寫上回調函式,否則會報錯的
//引數,resolve和reject ,由 JavaScript 引擎提供,不用自己部署。
}).then(function(value){
//成功的返回值
靜態方法 Promise.resolve返回一個promise物件,這個promise物件是被解析後(resolved)的
},function(error){
//失敗的返回值
})
關於這兩個引數:(貌似都是返回一個物件啊)
1.Promise.resolve()方法
靜態方法 Promise.resolve返回一個promise物件,這個promise物件是被解析後(resolved)的
語法:
Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);
2.Promise.reject(reason)方法返回一個用reason拒絕的Promise\
擴充套件結束,我們來分析這個案例:
執行結果:
執行for迴圈之前-->程式碼執行結束了--->執行了then函數了--->定時器開始了
結構分析:
1.由上到下執行
setTimeout() 放在全域性的非同步執行佇列中(巨集任務)
2.建立promise物件
回撥函式立即執行,列印執行for迴圈之前
then 是非同步的,存在當前的非同步執行佇列中(微任務)
3.全域性
程式碼執行結束了
4.返回到那個內部的非同步 Event Loop裡面執行
執行then函式
5,執行全域性的非同步佇列中的函式
執行完主程式之後
先看看微任務有未執行的嗎,如果有,就先執行他-=--這不是開小灶嗎
之後執行紅任務
疑惑:
就兩個執行緒
這個多了一個,算是巢狀嗎????
還有一個坑:
程式碼:
setTimeout(
function(){
console.log('執行了')
},3000 )
其實,不是3s之後執行
而是,3s之後,被推入Event Loop執行佇列中
主程式有空閒,就來執行該程式
執行的條件
所以只有滿足 (1)3秒後 (2)主執行緒空閒,同時滿足時,才會3秒後執行該函式