成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【11】JavaScript 線程機(jī)制與事件機(jī)制

fobnn / 2609人閱讀

摘要:線程機(jī)制與事件機(jī)制一進(jìn)程與線程進(jìn)程程序的一次執(zhí)行,它占有一片獨(dú)有的內(nèi)存空間。事件響應(yīng)模塊負(fù)責(zé)事件的管理。當(dāng)事件發(fā)生時管理模塊會將回調(diào)函數(shù)及其數(shù)據(jù)添加到回調(diào)列隊(duì)中。但是子線程完全受主線程控制,且不得操作。向另一個線程發(fā)送消息。

JavaScript線程機(jī)制與事件機(jī)制 一、進(jìn)程與線程 進(jìn)程(process

程序的一次執(zhí)行,它占有一片獨(dú)有的內(nèi)存空間。

可以通過windows任務(wù)管理器查看進(jìn)程。

線程(thread

是進(jìn)程內(nèi)的一個獨(dú)立執(zhí)行單元。

是程序執(zhí)行的一個完整流程。

CPU的最小調(diào)度單元。

進(jìn)程與線程圖解

相關(guān)知識

應(yīng)用程序必須運(yùn)行在某個進(jìn)程的某個線程上。

一個進(jìn)程中至少有一個運(yùn)行的線程:主線程,進(jìn)程啟動后自動創(chuàng)建。

一個進(jìn)程中也可以同時運(yùn)行多個線程,我們會說程序是多線程運(yùn)行的。

一個進(jìn)程內(nèi)的數(shù)據(jù)可以供其中的多個線程中直接共享。

多個進(jìn)程之間的數(shù)據(jù)是不能直接共享的。

線程池(thread pool):保存多個線程對象的容器,實(shí)現(xiàn)線程對象的反復(fù)利用。

相關(guān)問題

(1)何為多進(jìn)程與多線程?

多進(jìn)程運(yùn)行:一個應(yīng)用程序可以同時啟動多個實(shí)例運(yùn)行。

多線程:在一個進(jìn)程內(nèi),同時有多個線程運(yùn)行。

(2)比較單線程與多線程?

多線程

優(yōu)點(diǎn):能有效提升CPU的利用率。

缺點(diǎn):

創(chuàng)建多線程開銷。

線程間切換開銷。

死鎖與狀態(tài)同步問題。

單線程

優(yōu)點(diǎn):順序編程簡單易懂。

缺點(diǎn):效率低。

(3)JS是單線程還是多線程?

JS是單線程運(yùn)行的。

但是使用H5中的 Web Workers可以多線程運(yùn)行。

(4)瀏覽器運(yùn)行是單線程還是多線程?

瀏覽器都是多線程運(yùn)行的。

(5)瀏覽器運(yùn)行是單進(jìn)程還是多進(jìn)程?

有的是單進(jìn)程:

老版Firefox

老版IE

有的是多進(jìn)程:

Chrome

新版Firefox

新版IE

如何查看瀏覽器是否是多進(jìn)程運(yùn)行的呢?

任務(wù)管理器==>進(jìn)程

二、瀏覽器內(nèi)核

(1)瀏覽器內(nèi)核是支撐瀏覽器運(yùn)行的最核心的程序。

(2)不同的瀏覽器內(nèi)核不一樣:

Chrome,Safariwebkit

FirefoxGecko

IETrident

360,搜狗等國內(nèi)瀏覽器:Trident+webkit

(3)內(nèi)核由很多模塊組成:

主線程

js引擎模塊:負(fù)責(zé)js程序的編譯與運(yùn)行。

html,css文檔解析模塊:負(fù)責(zé)頁面文本的解析。

DOM/CSS模塊:負(fù)責(zé)DOM/CSS在內(nèi)存中的相關(guān)處理。

布局和渲染模塊:負(fù)責(zé)頁面的布局和效果的繪制(內(nèi)存中的對象)

分線程

定時器模塊:負(fù)責(zé)定時器的管理。

DOM事件響應(yīng)模塊:負(fù)責(zé)事件的管理。

網(wǎng)絡(luò)請求模塊:負(fù)責(zé)服務(wù)器請求(常規(guī)/ajax)。

三、定時器引發(fā)的思考

(1)定時器真是定時執(zhí)行的嗎?

定時器并不能保證真正定時執(zhí)行。

一般會延遲一丁點(diǎn)(可以接受), 也有可能延遲很長時間(不能接受)。



document.getElementById("btn").onclick = function () {
  var start = Date.now()
  console.log("啟動定時器前...")
  setTimeout(function () {
    console.log("定時器執(zhí)行了", Date.now()-start)
  }, 200)
  console.log("啟動定時器后...")
}

給上面回調(diào)函數(shù)加一個長時間的任務(wù):

document.getElementById("btn").onclick = function () {
  var start = Date.now()
  console.log("啟動定時器前...")
  setTimeout(function () {
    console.log("定時器執(zhí)行了", Date.now()-start)
  }, 200)
  console.log("啟動定時器后...")
  // 做一個長時間的工作
  for (var i = 0; i < 1000000000; i++) {}
}

結(jié)果:

同步任務(wù)執(zhí)行完之后才會執(zhí)行異步任務(wù)。

(2)定時器回調(diào)函數(shù)是在分線程執(zhí)行的嗎?

在主線程執(zhí)行的, js是單線程的。

(3)定時器是如何實(shí)現(xiàn)的?

事件循環(huán)模型(后面講)。

四、JS是單線程執(zhí)行的

(1)如何證明js執(zhí)行是單線程的?

setTimeout()的回調(diào)函數(shù)是在主線程執(zhí)行的。

定時器回調(diào)函數(shù)只有在運(yùn)行棧中的代碼全部執(zhí)行完后才有可能執(zhí)行。

(2)為什么js要用單線程模式, 而不用多線程模式?

JavaScript的單線程,與它的用途有關(guān)。

作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。

這決定了它只能是單線程,否則會帶來很復(fù)雜的同步問題

(3)代碼的分類:

初始化代碼

回調(diào)代碼

(4)js引擎執(zhí)行代碼的基本流程

先執(zhí)行初始化代碼: 包含一些特別的代碼 ,回調(diào)函數(shù)(異步執(zhí)行)

設(shè)置定時器

綁定監(jiān)聽

發(fā)送ajax請求

后面在某個時刻才會執(zhí)行回調(diào)代碼。

五、瀏覽器的事件循環(huán)(輪詢)模型 瀏覽器的事件循環(huán)模型原理圖

相關(guān)重要概念

(1)執(zhí)行棧

execution stack

所有的代碼都是在此空間中執(zhí)行的。

(2)瀏覽器內(nèi)核

browser core

js引擎模塊(在主線程處理)

其它模塊(在主/分線程處理)

(3)任務(wù)隊(duì)列(callback queue)

? task queue

(4)消息隊(duì)列(callback queue)

? message queue

(5)事件隊(duì)列(callback queue)

? event queue

(6)事件輪詢

event loop

從任務(wù)隊(duì)列中循環(huán)取出回調(diào)函數(shù)放入執(zhí)行棧中處理(一個接一個)。

(7)事件驅(qū)動模型

? event-driven interaction model

(8)請求響應(yīng)模型

? request-response model

執(zhí)行流程

(1)所有代碼分類:

初始化執(zhí)行代碼:包含綁定dom事件監(jiān)聽, 設(shè)置定時器, 發(fā)送ajax請求的代碼。

回調(diào)執(zhí)行代碼:處理回調(diào)邏輯。

(2)js引擎執(zhí)行代碼的基本流程:

初始化代碼===>回調(diào)代碼

(3)模型的2個重要組成部分:

事件管理模塊

回調(diào)隊(duì)列

(4)模型的運(yùn)轉(zhuǎn)流程

? (a)執(zhí)行初始化代碼, 將事件回調(diào)函數(shù)交給對應(yīng)模塊管理。

? (b)當(dāng)事件發(fā)生時, 管理模塊會將回調(diào)函數(shù)及其數(shù)據(jù)添加到回調(diào)列隊(duì)中。

? (c)只有當(dāng)初始化代碼執(zhí)行完后(可能要一定時間), 才會遍歷讀取回調(diào)隊(duì)列中的回調(diào)函數(shù)執(zhí)行。

六、H5 Web Workers(多線程) 介紹

Web WorkersHTML5 提供的一個Javascript多線程解決方案。

我們可以將一些大計算量的代碼交由Web Worker運(yùn)行而不凍結(jié)用戶界面。

但是子線程完全受主線程控制,且不得操作DOM。所以,這個新標(biāo)準(zhǔn)并沒有改變JavaScript單線程的本質(zhì)

使用

相關(guān)API

Worker: 構(gòu)造函數(shù), 加載分線程執(zhí)行的js文件。

Worker.prototype.onmessage: 用于接收另一個線程的回調(diào)函數(shù)。

Worker.prototype.postMessage: 向另一個線程發(fā)送消息。

創(chuàng)建在分線程執(zhí)行的JS文件

var onmessage = function (event){ //不能用函數(shù)聲明
    console.log("onMessage()22");
    var upper = event.data.toUpperCase();//通過event.data獲得發(fā)送來的數(shù)據(jù)
    postMessage( upper );//將獲取到的數(shù)據(jù)發(fā)送回主線程
}

在主線程中的JS中發(fā)消息并設(shè)置回調(diào)

//創(chuàng)建一個Worker對象并向它傳遞將在新線程中執(zhí)行的腳本的URL
var worker = new Worker("worker.js");  
//接收worker傳過來的數(shù)據(jù)函數(shù)
worker.onmessage = function (event) {     
    console.log(event.data);             
};
//向worker發(fā)送數(shù)據(jù)
worker.postMessage("hello world");    
圖解

應(yīng)用練習(xí)
編程實(shí)現(xiàn)斐波那契數(shù)列(Fibonacci sequence)的計算

F(0)=0,F(xiàn)(1)=1,..... F(n)=F(n-1)+F(n-2)

直接在主線程:

var fibonacci =function(n) {
    return n <2 ? n : fibonacci(n -1) + fibonacci(n -2);
};
console.log(fibonacci(48));

使用Web Workers在分線程:

主線程:

var worker = new Worker("worker2.js");
worker.addEventListener("message", function (event) {
    var timer2 = new Date().getTime();
    console.log("結(jié)果:" + event.data, "時間:" + timer2, "用時:" + ( timer2 - timer ));
}, false);
var timer = new Date().getTime();
console.log("開始計算: ", "時間:" + timer);
setTimeout(function () {
    console.log("定時器函數(shù)在計算數(shù)列時執(zhí)行了", "時間:" + new Date().getTime());
}, 1000);
worker.postMessage(40);
console.log("我在計算數(shù)列的時候執(zhí)行了", "時間:" + new Date().getTime());

分線程:

var fibonacci =function(n) {
    return n <2 ? n : fibonacci(n -1) + fibonacci(n -2);
};
var onmessage = function(event) {
    var n = parseInt(event.data, 10);
    postMessage(fibonacci(n));
};

不足

慢。

不能跨域加載JS。

worker內(nèi)代碼不能訪問DOM(更新UI)。

不是每個瀏覽器都支持這個新特性。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105093.html

相關(guān)文章

  • JSNode.js中的事件循環(huán)

    摘要:的單線程,與它的用途有關(guān)。特點(diǎn)的顯著特點(diǎn)異步機(jī)制事件驅(qū)動。隊(duì)列的讀取輪詢線程,事件的消費(fèi)者,的主角。它將不同的任務(wù)分配給不同的線程,形成一個事件循環(huán),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給引擎。 這兩天跟同事同事討論遇到的一個問題,js中的event loop,引出了chrome與node中運(yùn)行具有setTimeout和Promise的程序時候執(zhí)行結(jié)果不一樣的問題,從而引出了Nodejs的...

    abson 評論0 收藏0
  • 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制

    摘要:事件完成,回調(diào)函數(shù)進(jìn)入。主線程從讀取回調(diào)函數(shù)并執(zhí)行。終于執(zhí)行完了,終于從進(jìn)入了主線程執(zhí)行。遇到,立即執(zhí)行。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)和。事件循環(huán)事件循環(huán)是實(shí)現(xiàn)異步的一種方法,也是的執(zhí)行機(jī)制。 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果讀完本文還不懂,可以揍我。不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發(fā)工作...

    dreambei 評論0 收藏0
  • JavaScript執(zhí)行機(jī)制

    摘要:事件循環(huán)事件循環(huán)是實(shí)現(xiàn)異步的一種方法,也是的執(zhí)行機(jī)制。最后的最后是一門單線程語言是的執(zhí)行機(jī)制部分內(nèi)容轉(zhuǎn)自 1.單線程 javascript是一門單線程語言 2.javascript事件循環(huán) 同步任務(wù) 異步任務(wù) showImg(https://segmentfault.com/img/bVbufUd?w=1268&h=1062);除了廣義的同步任務(wù)和異步任務(wù),我們對任務(wù)有更精細(xì)的定義...

    ralap 評論0 收藏0
  • 徹底弄懂 JavaScript 執(zhí)行機(jī)制

    摘要:關(guān)于這部分有嚴(yán)格的文字定義,但本文的目的是用最小的學(xué)習(xí)成本徹底弄懂執(zhí)行機(jī)制,所以同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行場所,同步的進(jìn)入主線程,異步的進(jìn)入并注冊函數(shù)。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)和。 不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發(fā)工作,我們經(jīng)常會遇到這樣的情況:給定的幾行代碼,我們需要知道其輸出內(nèi)容和順序。 因?yàn)閖avascr...

    gyl_coder 評論0 收藏0
  • 深入前端-徹底搞懂JS的運(yùn)行機(jī)制

    摘要:瀏覽器是多進(jìn)程的詳情看我上篇總結(jié)瀏覽器執(zhí)行機(jī)制的文章深入前端徹底搞懂瀏覽器運(yùn)行機(jī)制瀏覽器每打開一個標(biāo)簽頁,就相當(dāng)于創(chuàng)建了一個獨(dú)立的瀏覽器進(jìn)程。執(zhí)行異步操作事件完成,回調(diào)函數(shù)進(jìn)入。主線程從讀取回調(diào)函數(shù)并執(zhí)行。 最近看了很多關(guān)于JS運(yùn)行機(jī)制的文章,每篇都獲益匪淺,但各有不同,所以在這里對這幾篇文章里說的很精辟的地方做一個總結(jié),參考文章鏈接見最后。本文博客地址 了解進(jìn)程和線程 進(jìn)程是應(yīng)用...

    luckyw 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<