搜尋
首頁web前端js教程nodejs中實作阻塞實例_node.js

node.js中與生俱來的單執行緒程式設計、回呼函數非同步式風格讓我們有時喜有時憂。先說單線程,很多人會費解於node.js的單線程如何能做到高並發?這個問題不是本文重點,點到為止。澄清一點,node.js的單線程僅僅指javascript引擎是單線程的,無論如何我們沒有辦法在javascript中實現多線程和阻塞(本文用到的方法同樣不是透過V8引擎實現同步的);但對於node .js的其他方面不代表不能多線程,例如IO。如果現在node.js遭受大量請求,而這些請求都是IO密集型的,那麼此時node每接受一個請求,在遇到耗時較長的IO操作時,javascript線程並不會一直在此等待,而是交出控制,在回調堆疊裡加入IO操作完成後要執行的操作(當回呼層級過多,存取數量過大,大量的回調鏈可能會爆棧)。而在這段時間內,node.js又可以處理其他請求了。所以對於node.js而言,雖然javascript是單線程的,每次只能處理一個請求,但javascript處理一個請求的時間往往較短(對於IO密集型應用而言),只要可以異步處理,那麼在處理的過程中,此次請求都會釋放控制,使node.js能處理其他請求。這並發請求的同時,IO其實一直處於並發狀態,減少處理請求的線程數,節約資源以增加IO的線程數,對於通常耗時很長的IO密集型請求來說,無疑能帶來性能上的提升。

前囉嗦嗦嗦地一直在強調IO密集型,其實是在強調node.js的強項。相應的,它的短板就是CPU密集型的請求。道理很簡單,javascript不會並發,只能一個請求完成後才能處理其他請求。一個請求處理的時間越長,其他請求等待的時間越長。同一時間只會有一個請求被處理,並發效能很低。

話說到這兒,我想申明一點:node.js不應該被阻塞;能非同步處理的方法非同步處理(如使用fs.readFile(),而非fs.syncReadFile()fs.readFileSync()方法) 。

node中不能阻塞,不代表node外不能阻塞。前面我們有講到fibers,現在,我們就來嘗試在fibers中實現阻塞。就以處理一個http請求為例吧:

複製程式碼 程式碼如下:

var Fiber = require('fibers');
var http = require("http");
Fiber(function () {
    var httpFiber = Fiber.current;
    var html = "";
    http.get("http://www.baidu.com", function (res) {
        var dataFiber = Fiber.current;
        res.on("data", function (data) {
            html = 數據;
        });
        res.on("end", function (data) {
            httpFiber.run();
        });
    });
    Fiber.yield();
    console.log(html);
}).run();

yield()、 run()這兩個方法還不了解的同學,請自行查閱《fibers in node》。


fibers的運作並不在node進程中,所以在fibers內部實作阻塞對node整體的效能並沒有影響。而且實現起來也是相當容易,只要在想阻塞的時候,把fiber yield掉。需要繼續運行,則執行 run()恢復fiber。在上面的例子中,我們希望當http.get請求發起時阻塞當前程序,當所有資料接收完成時,恢復程序。於是我們在呼叫http.get後使用 Fiber.yield()中斷此fiber。在對response的監聽中,如果觸發end事件顯示資料傳輸完成,於是在end的回呼函數中,呼叫Fiber.current.run()恢復fiber,這樣,後續的程式碼就以同步的方式拿到http.get請求的數據。

上面的範例只是提供一個思路。如果對這種想法進行一些抽象封裝,比如說,對有接受回呼函數為參數的非同步方法進行一步柯里化,在呼叫後中斷,並劫持回呼函數,以恢復程式的程式碼為回呼函數。取得非同步資料後,再程式觸發預定的回呼函數,這樣基本能實現非同步方法同步化。這段說得比較亂,基本上就是 fibers/future的實現思路,如果有興趣,請參考其原始碼

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Vercel是什么?怎么部署Node服务?Vercel是什么?怎么部署Node服务?May 07, 2022 pm 09:34 PM

Vercel是什么?本篇文章带大家了解一下Vercel,并介绍一下在Vercel中部署 Node 服务的方法,希望对大家有所帮助!

node.js gm是什么node.js gm是什么Jul 12, 2022 pm 06:28 PM

gm是基于node.js的图片处理插件,它封装了图片处理工具GraphicsMagick(GM)和ImageMagick(IM),可使用spawn的方式调用。gm插件不是node默认安装的,需执行“npm install gm -S”进行安装才可使用。

火了!新的JavaScript运行时:Bun,性能完爆Node火了!新的JavaScript运行时:Bun,性能完爆NodeJul 15, 2022 pm 02:03 PM

今天跟大家介绍一个最新开源的 javaScript 运行时:Bun.js。比 Node.js 快三倍,新 JavaScript 运行时 Bun 火了!

nodejs中lts是什么意思nodejs中lts是什么意思Jun 29, 2022 pm 03:30 PM

在nodejs中,lts是长期支持的意思,是“Long Time Support”的缩写;Node有奇数版本和偶数版本两条发布流程线,当一个奇数版本发布后,最近的一个偶数版本会立即进入LTS维护计划,一直持续18个月,在之后会有12个月的延长维护期,lts期间可以支持“bug fix”变更。

聊聊Node.js中的多进程和多线程聊聊Node.js中的多进程和多线程Jul 25, 2022 pm 07:45 PM

大家都知道 Node.js 是单线程的,却不知它也提供了多进(线)程模块来加速处理一些特殊任务,本文便带领大家了解下 Node.js 的多进(线)程,希望对大家有所帮助!

node爬取数据实例:聊聊怎么抓取小说章节node爬取数据实例:聊聊怎么抓取小说章节May 02, 2022 am 10:00 AM

node怎么爬取数据?下面本篇文章给大家分享一个node爬虫实例,聊聊利用node抓取小说章节的方法,希望对大家有所帮助!

深入浅析Nodejs中的net模块深入浅析Nodejs中的net模块Apr 11, 2022 pm 08:40 PM

本篇文章带大家带大家了解一下Nodejs中的net模块,希望对大家有所帮助!

怎么获取Node性能监控指标?获取方法分享怎么获取Node性能监控指标?获取方法分享Apr 19, 2022 pm 09:25 PM

怎么获取Node性能监控指标?本篇文章来和大家聊聊Node性能监控指标获取方法,希望对大家有所帮助!

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具