javascript的事件驅(qū)動(dòng)機(jī)制是什么

這篇文章主要介紹“javascript的事件驅(qū)動(dòng)機(jī)制是什么”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“javascript的事件驅(qū)動(dòng)機(jī)制是什么”文章能幫助大家解決問(wèn)題。

我們注重客戶提出的每個(gè)要求,我們充分考慮每一個(gè)細(xì)節(jié),我們積極的做好成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)服務(wù),我們努力開拓更好的視野,通過(guò)不懈的努力,成都創(chuàng)新互聯(lián)公司贏得了業(yè)內(nèi)的良好聲譽(yù),這一切,也不斷的激勵(lì)著我們更好的服務(wù)客戶。 主要業(yè)務(wù):網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),微信小程序開發(fā),網(wǎng)站開發(fā),技術(shù)開發(fā)實(shí)力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫(kù)的技術(shù)開發(fā)工程師。

javascript采用事件驅(qū)動(dòng)。JavaScript是一種基于對(duì)象和事件驅(qū)動(dòng)并具有安全性能的腳本語(yǔ)言,它采用事件驅(qū)動(dòng)的機(jī)制來(lái)響應(yīng)用戶操作,當(dāng)用戶對(duì)某個(gè)html元素進(jìn)行操作的時(shí)候,會(huì)產(chǎn)生一個(gè)事件,該事件會(huì)驅(qū)動(dòng)某些函數(shù)來(lái)處理。

本教程操作環(huán)境:windows7系統(tǒng)、javascript1.8.5版、Dell G3電腦。

JavaScript是一種基于對(duì)象和事件驅(qū)動(dòng)并具有安全性能的腳本語(yǔ)言。

本文分別講解了javascript在瀏覽器端和服務(wù)器端(node.js)的事件驅(qū)動(dòng)機(jī)制,期間加入了一些異步編程的例子加深理解。

javascript 在瀏覽器端的事件驅(qū)動(dòng)機(jī)制

首先,javascript 在瀏覽器端運(yùn)行是單線程的,這是由瀏覽器決定的,這是為了避免多線程執(zhí)行不同任務(wù)會(huì)發(fā)生沖突的情況。也就是說(shuō)我們寫的javascript 代碼只在一個(gè)線程上運(yùn)行,稱之為主線程(HTML5提供了web worker API可以讓瀏覽器開一個(gè)線程運(yùn)行比較復(fù)雜耗時(shí)的 javascript任務(wù),但是這個(gè)線程仍受主線程的控制)。單線程的話,如果我們做一些“sleep”的操作比如說(shuō):

var now = + new Date()while (+new Date() <= now + 1000){
//這是一個(gè)耗時(shí)的操所
}

那么在這將近一秒內(nèi),線程就會(huì)被阻塞,無(wú)法繼續(xù)執(zhí)行下面的任務(wù)。

還有些操作比如說(shuō)獲取遠(yuǎn)程數(shù)據(jù)、I/O操作等,他們都很耗時(shí),如果采用同步的方式,那么進(jìn)程在執(zhí)行這些操作時(shí)就會(huì)因?yàn)楹臅r(shí)而等待,就像上面那樣,下面的任務(wù)也只能等待,這樣效率并不高。 為了解決單線程帶來(lái)的阻塞問(wèn)題很多操作系統(tǒng)實(shí)現(xiàn)了異步編程機(jī)制,瀏覽器中也是這么做的,主要表現(xiàn)如下:

  • 只在主線程中運(yùn)行 javascript 代碼

  • 主線程一啟動(dòng)就進(jìn)入事件循環(huán),整個(gè)過(guò)程就是不斷的循環(huán),不斷地執(zhí)行回調(diào)函數(shù)

  • 遇到網(wǎng)絡(luò)請(qǐng)求、I/O操作等時(shí),瀏覽器會(huì)單開工作線程來(lái)處理,并設(shè)置相應(yīng)的觀察者,然后立即返回主線程,主線程繼續(xù)執(zhí)行下面的任務(wù)

  • 瀏覽器開的線程處理好任務(wù)或者有監(jiān)聽的事件后會(huì)用得到的數(shù)據(jù)(或輸入)形成一個(gè)事件,放在相應(yīng)觀察者的事件隊(duì)列中,事件隊(duì)列是在主線程中

  • 主線程不斷的循環(huán),不斷檢查事件隊(duì)列,通過(guò)遍歷事件依次執(zhí)行事件對(duì)應(yīng)的回調(diào)函數(shù)

注意:下圖中的消息隊(duì)列是存儲(chǔ)在主線程中

javascript的事件驅(qū)動(dòng)機(jī)制是什么

上圖中,假設(shè)你發(fā)起了一個(gè)AJAX請(qǐng)求,無(wú)論你把這個(gè)請(qǐng)求寫在什么地方,它始終都在回調(diào)函數(shù)里。因?yàn)槭录?qū)動(dòng)機(jī)制就是把一切抽象為事件,代碼開始執(zhí)行也是一個(gè)事件,也會(huì)隱式調(diào)用回調(diào)函數(shù),調(diào)用回調(diào)函數(shù)就是開始執(zhí)行代碼。然后主線程發(fā)起異步任務(wù)后就會(huì)隨即返回,繼續(xù)執(zhí)行"代碼開始事件"對(duì)應(yīng)回調(diào)函數(shù)里下面的代碼,等到這個(gè)回調(diào)函數(shù)執(zhí)行完畢,就會(huì)執(zhí)行下一個(gè)事件。在這之間,Ajax線程會(huì)完成請(qǐng)求,然后把請(qǐng)求完成的事件(包含返回的數(shù)據(jù))發(fā)送到事件隊(duì)尾中等待處理,等到主線程執(zhí)行到這個(gè)事件時(shí),指定的回調(diào)函數(shù)即被執(zhí)行。

大概是這樣。如果有幾處疑問(wèn)的話請(qǐng)往下看。下面結(jié)合代碼講一下具體的過(guò)程和機(jī)制。

console.log("開始");setTimeout(function(){
  console.log('延遲執(zhí)行的')
}, 1000);setTimeout(function(){
  console.log('立即執(zhí)行的')
}, 0);
console.log('結(jié)束') //開始 結(jié)束 立即執(zhí)行的 延遲執(zhí)行的

watcher機(jī)制

watcher,觀察者,是事件驅(qū)動(dòng)系統(tǒng)重要的機(jī)制。

setTimeout稱為定時(shí)器,這是瀏覽器給的API。每當(dāng)你使用定時(shí)器,這個(gè)函數(shù)將會(huì)設(shè)置一個(gè)watcher,觀察者。主線程會(huì)不斷的循環(huán),不斷的"經(jīng)過(guò)"這里檢查時(shí)間,當(dāng)主線程檢查時(shí)間間隔符合要求時(shí),就會(huì)產(chǎn)生一個(gè)定時(shí)器事件,加入到這個(gè)watcher事件隊(duì)列中并執(zhí)行回調(diào)函數(shù)。因此執(zhí)行setTimeout只是在時(shí)間到的時(shí)候產(chǎn)生了要調(diào)用回調(diào)函數(shù)的消息加入到了事件隊(duì)列中,因此,回調(diào)函數(shù)并不一定在指定的時(shí)間時(shí)調(diào)用,它取決于前面有多少等待處理的事件。

javascript的事件驅(qū)動(dòng)機(jī)制是什么

剛才講的是定時(shí)器觀察者,還有I/O觀察者、網(wǎng)絡(luò)請(qǐng)求觀察者、鼠標(biāo)事件觀察者、鍵盤事件觀察者等等等等,我們經(jīng)常遇到事件監(jiān)聽函數(shù)會(huì)讓你綁定一個(gè)回調(diào)函數(shù),這種監(jiān)聽函數(shù)一般就會(huì)設(shè)置watcher,其他線程產(chǎn)生的事件也會(huì)放到相應(yīng)watcher的事件隊(duì)列中,因此每個(gè)watcher會(huì)產(chǎn)生自己的事件隊(duì)列。主線程在循環(huán)的時(shí)候,實(shí)際上是在依次調(diào)用這些watcher,檢查每個(gè)watcher的事件隊(duì)列,有事件就執(zhí)行相應(yīng)的回調(diào)。

javascript的事件驅(qū)動(dòng)機(jī)制是什么

它的過(guò)程就是 :

  • 進(jìn)程一啟動(dòng)就進(jìn)入事件循環(huán)

  • 有監(jiān)聽就添加watcher

  • 遍歷watcher下的事件隊(duì)列

  • 執(zhí)行下一個(gè)watcher

事件驅(qū)動(dòng)機(jī)制,它會(huì)有各種各樣的事件,大量的事件,它所做的一切都跟處理事件有關(guān)。但并不是所有的事件都有watcher,如果都有,主進(jìn)程任務(wù)會(huì)變得非常繁重,況且有些事件我們并不關(guān)心,例如你只寫了一個(gè)定時(shí)器,代表你關(guān)心這個(gè)事件,那么點(diǎn)擊事件、網(wǎng)絡(luò)請(qǐng)求事件就不用關(guān)心,因?yàn)槟愀揪蜎](méi)寫啊,也就沒(méi)有watcher

javascript 在 node.js上的事件驅(qū)動(dòng)機(jī)制

javascript 在 node.js上的事件驅(qū)動(dòng)機(jī)制與瀏覽器端大致相同,都是單線程,都有event loop,上面講的javascript在瀏覽器端的事件循環(huán)機(jī)制在node上也是大致一樣的,不同的是執(zhí)行者何執(zhí)行者的行為不一樣,因?yàn)樗麄冴P(guān)注的任務(wù)不一樣:

  • node端異步機(jī)制和事件循環(huán)更加純粹一些。node為了支持高并發(fā),所有的API幾乎都是異步的,這樣會(huì)充分利用操作系統(tǒng)的其他線程來(lái)幫忙完成任務(wù),主線程只負(fù)責(zé)事件消費(fèi)。例如當(dāng)web server接收到請(qǐng)求,node就把它關(guān)閉,交給其他線程進(jìn)行處理,然后去服務(wù)下一個(gè)web請(qǐng)求。當(dāng)這個(gè)請(qǐng)求完成,它被放到處理隊(duì)列,當(dāng)?shù)竭_(dá)隊(duì)列開頭,這個(gè)結(jié)果被返回給用戶。這樣的話webserver一直接受請(qǐng)求而不等待任何讀寫操作,這種非阻塞型I/O性能很強(qiáng)。

  • 瀏覽器端是瀏覽器負(fù)責(zé)執(zhí)行BOM API,管理線程,處理用戶輸入信息等,在node上是node的一個(gè)核心庫(kù)libuv負(fù)責(zé)執(zhí)行node API,管理主線程(運(yùn)行javascript)和工作線程等。

  • 因?yàn)榍岸撕秃蠖岁P(guān)注的內(nèi)容不同,因此兩個(gè)運(yùn)行環(huán)境的API也專注于不同的任務(wù)

關(guān)于“javascript的事件驅(qū)動(dòng)機(jī)制是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

新聞標(biāo)題:javascript的事件驅(qū)動(dòng)機(jī)制是什么
文章網(wǎng)址:http://muchs.cn/article30/gdsiso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、品牌網(wǎng)站制作網(wǎng)站設(shè)計(jì)公司、電子商務(wù)、企業(yè)網(wǎng)站制作、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名