最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Node.js中的定時器

 更新時間:2015年06月18日 11:51:00   投稿:hebedich  
本文給大家分享的是Node.js中的定時器的相關資料,十分的全面細致,有需要的小伙伴可以參考下。

Node.js中定時器的實現(xiàn)

上一篇博文提到,在Node中timer并不是通過新開線程來實現(xiàn)的,而是直接在event loop中完成。下面通過幾個JavaScript的定時器示例以及Node相關源碼來分析在Node中,timer功能到底是怎么實現(xiàn)的。

JavaScript中定時器功能的特點

無論是Node還是瀏覽器中,都有setTimeout和setInterval這兩個定時器函數(shù),并且其工作特點基本相同,因此下面僅以Node為例進行分析。

我們知道,JavaScript中的定時器并不同于計算機底層的定時中斷。中斷到來時,當前執(zhí)行代碼會被打斷,轉去執(zhí)行定時中斷處理函數(shù)。而JavaScript的定時器到時,如果當前執(zhí)行線程沒有正在執(zhí)行的代碼,則執(zhí)行相應的回調函數(shù);如果當前有代碼在執(zhí)行中,JavaScript引擎既不會中斷當前代碼轉去執(zhí)行回調,也不會開新的線程執(zhí)行回調,而是當前代碼執(zhí)行完畢之后才去處理。

console.time('A')
setTimeout(function () {
  console.timeEnd('A');
}, 100);
var i = 0;
for (; i < 100000; i++) { }

執(zhí)行上面的代碼,可以看到最終輸出的時間并不是100ms左右,而是數(shù)秒。這說明在循環(huán)完成之前,定時回調函數(shù)確實沒有被執(zhí)行,而是推遲到了循環(huán)結束。實際上在JavaScript代碼執(zhí)行中,所有的事件都無法得到處理,必須等到當前代碼全部完成,才能去處理新的事件。這就是為什么在瀏覽器中運行耗時JavaScript代碼時,瀏覽器會失去響應。為了應對這種情況,我們可以采取Yielding Processes的技巧,將耗時的代碼分成小塊(chunks),每處理完一塊就執(zhí)行一次setTimeout,約定在一小段時間后才處理下一塊,而在這段空閑時間里,瀏覽器/Node可以去處理排隊中的事件。

補充資料

在JavaScript 高級程序設計 第三版第22章高級技巧中對高級定時器以及Yielding Processes有較詳細的討論。

Node中的timer實現(xiàn)

libuv對uv_loop_t類型的初始化

上一篇博文提到Node會調用libuv的uv_run函數(shù)啟動default_loop_ptr進行事件調度,default_loop_ptr指向一個uv_loop_t類型的變量default_loop_struct。Node啟動時會調用uv_loop_init(&default_loop_struct)對其進行初始化,uv_loop_init函數(shù)節(jié)選如下:

int uv_loop_init(uv_loop_t* loop) {
 ...
 loop->time = 0;
 uv_update_time(loop);
 ...
}

可以看到loop的time字段先被賦值為0,之后調用uv_update_time函數(shù),這會將最新的計數(shù)時間賦給loop.time。

初始化完成之后,default_loop_struct.time就有了一個初始值,與時間有關的操作都會與此值進行比較從而確定是否調用相應回調函數(shù)。

libuv的事件調度核心

前面提到uv_run函數(shù)就是libuv庫實現(xiàn)event loop的核心部分,下面是其流程圖:

這里簡述一下上面與定時器相關的邏輯:

更新當前l(fā)oop的time字段,這個字段標志著當前l(fā)oop概念下的“現(xiàn)在”;

檢查loop是否alive,也就是說檢查loop中是否還有需要處理的任務(handlers/requests),如果沒有就不必循環(huán)了;
檢查注冊過的timer,如果某一個timer中指定的時間落后于當前時間了,說明該timer已到時,于是執(zhí)行其對應的回調函數(shù);
執(zhí)行一次I/O polling(即阻塞住線程,等待I/O事件發(fā)生),如果在下一個timer到期時還沒有任何I/O完成,則停止等待,執(zhí)行下一個timer的回調。

如果發(fā)生了I/O事件,則執(zhí)行對應的回調;由于執(zhí)行回調的時間里可能又有timer到期了,這里要再次檢查timer并執(zhí)行回調。
(實際上(4.)這里比較復雜,不僅僅是一步操作,這樣描述僅是為了不涉及其他細節(jié),而專注于timer的實現(xiàn)。)
Node會一直調用uv_run直到loop不再alive。

Node中的timer_wrap與timers

Node中有一個TimerWrap類,被注冊為Node內部的timer_wrap模塊。

NODE_MODULE_CONTEXT_AWARE_BUILTIN(timer_wrap, node::TimerWrap::Initialize)
其中TimerWrap類基本上就是對uv_timer_t的一個直接封裝,NODE_MODULE_CONTEXT_AWARE_BUILTIN是Node用于注冊built-in模塊的宏。

經過這一步操作,JavaScript就可以拿到這個模塊進行操作了。src/lib/timers.js文件使用JavaScript的形式把timer_wrap的功能封裝起來,并導出了exports.setTimeout, exports.setInterval, exports.setImmediate等函數(shù)。

Node啟動與global初始化

上一篇提到Node啟動時會載入執(zhí)行環(huán)境LoadEnvironment(env),這個函數(shù)中非常重要的一步就是載入src/node.js并執(zhí)行,src/node.js會載入指定的模塊并初始化global和process。當然,setTimeout等函數(shù)也會被src/node.js綁定到global對象上。

以上所述就是本文的全部內容了,希望大家能夠喜歡。

相關文章

  • Node.js中操作MongoDB的CRUD操作指南

    Node.js中操作MongoDB的CRUD操作指南

    在Node.js中操作MongoDB常見的庫有mongodb原生驅動和mongoose等,本文將使用mongodb官方驅動包來進行示例,在開始之前,請確保已經安裝了MongoDB數(shù)據庫并且在本地啟動了MongoDB服務,需要的朋友可以參考下
    2024-01-01
  • Nodejs 和 Electron ubuntu下快速安裝過程

    Nodejs 和 Electron ubuntu下快速安裝過程

    本文較為詳細的給大家介紹了Nodejs 和 Electron ubuntu下快速安裝過程,非常不錯,具有一定的參考借鑒價值,感興趣的朋友跟隨腳本之家小編一起學習吧
    2018-05-05
  • node.js報錯:Cannot find module ''ejs''的解決辦法

    node.js報錯:Cannot find module ''ejs''的解決辦法

    最近發(fā)現(xiàn)了node.js居然報錯了,錯誤提示為:Cannot find module 'ejs',后來找了找資料發(fā)現(xiàn)解決的方法其實很簡單,下面通過這篇文章來一起看看吧,希望對同樣遇到這個問題的朋友們能有所幫助。
    2016-12-12
  • 使用?Node.js和Express搭建服務器的過程步驟詳解

    使用?Node.js和Express搭建服務器的過程步驟詳解

    Node.js?是一個開源、跨平臺的?JavaScript?運行時環(huán)境,這篇文章主要介紹了如何使用?Node.js和Express搭建服務器,需要的朋友可以參考下
    2023-09-09
  • npm 語義版本控制詳解

    npm 語義版本控制詳解

    這篇文章主要介紹了npm 語義版本控制詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • node模塊機制與異步處理詳解

    node模塊機制與異步處理詳解

    這篇文章主要介紹了node模塊機制與異步處理詳解的相關資料,需要的朋友可以參考下
    2016-03-03
  • Node.js Windows Binary二進制文件安裝方法

    Node.js Windows Binary二進制文件安裝方法

    這篇文章主要介紹了Node.js Windows Binary二進制文件安裝,本文給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-05-05
  • 基于promise.js實現(xiàn)nodejs的promises庫

    基于promise.js實現(xiàn)nodejs的promises庫

    promise是JavaScript實現(xiàn)優(yōu)雅編程的一個非常不錯的輕量級框架。該框架可以讓你從雜亂的多重異步回調代碼中解脫出來,并把精力集中到你的業(yè)務邏輯上。
    2014-07-07
  • 一文詳解如何在IDEA中配置Node.js

    一文詳解如何在IDEA中配置Node.js

    idea中支持運行很多種編程語言,只需要在電腦中安裝好對應的語言環(huán)境,下面這篇文章主要給大家介紹了關于如何在IDEA中配置Node.js的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • node.js基于fs模塊對系統(tǒng)文件及目錄進行讀寫操作的方法詳解

    node.js基于fs模塊對系統(tǒng)文件及目錄進行讀寫操作的方法詳解

    這篇文章主要介紹了node.js基于fs模塊對系統(tǒng)文件及目錄進行讀寫操作的方法,結合實例形式分析了nodejs使用fs模塊針對文件與目錄的讀寫、創(chuàng)建、刪除等相關操作技巧,需要的朋友可以參考下
    2017-11-11

最新評論

阆中市| 六安市| 五常市| 武定县| 开鲁县| 建湖县| 桃江县| 宣城市| 虹口区| 金秀| 崇文区| 千阳县| 贡觉县| 高州市| 青岛市| 阿巴嘎旗| 曲阳县| 云阳县| 唐河县| 河曲县| 泸定县| 岱山县| 班玛县| 福清市| 贞丰县| 通辽市| 南澳县| 阿勒泰市| 呼玛县| 进贤县| 仲巴县| 罗平县| 永定县| 灌阳县| 阿坝| 遂川县| 通化县| 阳谷县| 夹江县| 新平| 张家港市|