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

資訊專欄INFORMATION COLUMN

Node中的事件循環(huán)和異步API

atinosun / 1684人閱讀

摘要:異步在中,是在單線程中執(zhí)行的沒錯(cuò),但是內(nèi)部完成工作的另有線程池,使用一個(gè)主進(jìn)程和多個(gè)線程來模擬異步。在事件循環(huán)中,觀察者會(huì)不斷的找到線程池中已經(jīng)完成的請(qǐng)求對(duì)象,從中取出回調(diào)函數(shù)和數(shù)據(jù)并執(zhí)行。

1. 介紹

單線程編程會(huì)因阻塞I/O導(dǎo)致硬件資源得不到更優(yōu)的使用。多線程編程也因?yàn)榫幊讨械乃梨i、狀態(tài)同步等問題讓開發(fā)人員頭痛。
Node在兩者之間給出了它的解決方案:利用單線程,遠(yuǎn)離多線程死鎖、狀態(tài)同步等問題;利用異步I/O,讓單線程遠(yuǎn)離阻塞,以好使用CPU。

實(shí)際上,node只是在應(yīng)用層屬于單線程,底層其實(shí)通過libuv維護(hù)了一個(gè)阻塞I/O調(diào)用的線程池。

但是:在應(yīng)用層面,JS是單線程的,業(yè)務(wù)代碼中不能存在耗時(shí)過長(zhǎng)的代碼,否則可能會(huì)嚴(yán)重拖后續(xù)代碼(包括回調(diào))的處理。如果遇到需要復(fù)雜的業(yè)務(wù)計(jì)算時(shí),應(yīng)當(dāng)想辦法啟用獨(dú)立進(jìn)程或交給其他服務(wù)進(jìn)行處理。

1.1 異步I/O

在Node中,JS是在單線程中執(zhí)行的沒錯(cuò),但是內(nèi)部完成I/O工作的另有線程池,使用一個(gè)主進(jìn)程和多個(gè)I/O線程來模擬異步I/O。
當(dāng)主線程發(fā)起I/O調(diào)用時(shí),I/O操作會(huì)被放在I/O線程來執(zhí)行,主線程繼續(xù)執(zhí)行下面的任務(wù),在I/O線程完成操作后會(huì)帶著數(shù)據(jù)通知主線程發(fā)起回調(diào)。

1.2 事件循環(huán)

事件循環(huán)是Node的執(zhí)行模型,正是這種模型使得回調(diào)函數(shù)非常普遍。
在進(jìn)程啟動(dòng)時(shí),Node便會(huì)創(chuàng)建一個(gè)類似while(true)的循環(huán),執(zhí)行每次循環(huán)的過程就是判斷有沒有待處理的事件,如果有,就取出事件及其相關(guān)的回調(diào)并執(zhí)行他們,然后進(jìn)入下一個(gè)循環(huán)。如果不再有事件處理,就退出進(jìn)程。

Event loop是一種程序結(jié)構(gòu),是實(shí)現(xiàn)異步的一種機(jī)制。Event loop可以簡(jiǎn)單理解為:

所有任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。

主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。系統(tǒng)把異步任務(wù)放到"任務(wù)隊(duì)列"之中,然后主線程繼續(xù)執(zhí)行后續(xù)的任務(wù)。

一旦"執(zhí)行棧"中的所有任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列"。如果這個(gè)時(shí)候,異步任務(wù)已經(jīng)結(jié)束了等待狀態(tài),就會(huì)從"任務(wù)隊(duì)列"進(jìn)入執(zhí)行棧,恢復(fù)執(zhí)行。

主線程不斷重復(fù)上面的第三步。

Node中事件循環(huán)階段解析:

   ┌───────────────────────┐
┌─>│        timers         │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │
│  └──────────┬────────────┘      ┌───────────────┐
│  ┌──────────┴────────────┐      │   incoming:   │
│  │         poll          │<─────┤ connections,  │
│  └──────────┬────────────┘      │  data, etc.   │
│  ┌──────────┴────────────┐      └───────────────┘
│  │         check         │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    │
   └───────────────────────┘

每個(gè)階段都有一個(gè)FIFO的回調(diào)隊(duì)列(queue)要執(zhí)行。而每個(gè)階段有自己的特殊之處,簡(jiǎn)單說,就是當(dāng)event loop進(jìn)入某個(gè)階段后,會(huì)執(zhí)行該階段特定的(任意)操作,然后才會(huì)執(zhí)行這個(gè)階段的隊(duì)列里的回調(diào)。當(dāng)隊(duì)列被執(zhí)行完,或者執(zhí)行的回調(diào)數(shù)量達(dá)到上限后,event loop會(huì)進(jìn)入下個(gè)階段。

Phases Overview 階段總覽

timers: 這個(gè)階段執(zhí)行setTimeout()、setInterval()設(shè)定的回調(diào)。

I/O callbacks: 執(zhí)行幾乎所有的回調(diào),除了close callbacks、setTimeout()、setInterval()、setImmediate()的回調(diào)。

idle, prepare: 僅內(nèi)部使用。

poll: 獲取新的I/O事件;node會(huì)在適當(dāng)條件下阻塞在這里。

check: 執(zhí)行setImmediate()設(shè)定的回調(diào)。

close callbacks: 執(zhí)行比如socket.on("close", ...)的回調(diào)。

1. timers

一個(gè)timer指定一個(gè)下限時(shí)間而不是準(zhǔn)確時(shí)間,定時(shí)器setTimeout()setInterval()在達(dá)到這個(gè)下限時(shí)間后執(zhí)行回調(diào)。在指定的時(shí)間過后,timers會(huì)盡早的執(zhí)行回調(diào),但是系統(tǒng)調(diào)度或者其他回調(diào)的執(zhí)行可能會(huì)延遲它們。
從技術(shù)上來說,poll階段控制timers什么時(shí)候執(zhí)行,而執(zhí)行的具體位置在timers。
下限的時(shí)間有一個(gè)范圍:[1, 2147483647],如果設(shè)定的時(shí)間不在這個(gè)范圍,將被設(shè)置為1。

2. I/O callbacks

執(zhí)行除了close callbacks、setTimeout()、setInterval()、setImmediate()回調(diào)之外幾乎所有回調(diào),比如說TCP連接發(fā)生錯(cuò)誤。

3. idle, prepare

系統(tǒng)內(nèi)部的一些調(diào)用。

4. poll

這是最復(fù)雜的一個(gè)階段。poll會(huì)檢索新的I/O events,并且會(huì)在合適的時(shí)候阻塞,等待回調(diào)被加入。

poll階段有兩個(gè)主要的功能:一是執(zhí)行下限時(shí)間已經(jīng)達(dá)到的timers的回調(diào),一是處理poll隊(duì)列里的事件。
注:Node很多API都是基于事件訂閱完成的,這些API的回調(diào)應(yīng)該都在poll階段完成。

當(dāng)事件循環(huán)進(jìn)入poll階段:

poll隊(duì)列不為空的時(shí)候,事件循環(huán)肯定是先遍歷隊(duì)列并同步執(zhí)行回調(diào),直到隊(duì)列清空或執(zhí)行回調(diào)數(shù)達(dá)到系統(tǒng)上限。

poll隊(duì)列為空的時(shí)候,這里有兩種情況。

如果代碼已經(jīng)被setImmediate()設(shè)定了回調(diào),那么事件循環(huán)直接結(jié)束poll階段進(jìn)入check階段來執(zhí)行check隊(duì)列里的回調(diào)。

如果代碼沒有被設(shè)定setImmediate()設(shè)定回調(diào):

如果有被設(shè)定的timers,那么此時(shí)事件循環(huán)會(huì)檢查timers,如果有一個(gè)或多個(gè)timers下限時(shí)間已經(jīng)到達(dá),那么事件循環(huán)將繞回timers階段,并執(zhí)行timers的有效回調(diào)隊(duì)列。

如果沒有被設(shè)定timers,這個(gè)時(shí)候事件循環(huán)是阻塞在poll階段等待事件回調(diào)被加入poll隊(duì)列。

Node的很多API都是基于事件訂閱完成的,比如fs.readFile,這些回調(diào)應(yīng)該都在poll階段完成。

5. check

setImmediate()在這個(gè)階段執(zhí)行。

這個(gè)階段允許在poll階段結(jié)束后立即執(zhí)行回調(diào)。如果poll階段空閑,并且有被setImmediate()設(shè)定的回調(diào),那么事件循環(huán)直接跳到check執(zhí)行而不是阻塞在poll階段等待poll 事件們 (poll events)被加入。

注意:如果進(jìn)行到了poll階段,setImmediate()具有最高優(yōu)先級(jí),只要poll隊(duì)列為空且注冊(cè)了setImmediate(),無論是否有timers達(dá)到下限時(shí)間,setImmediate()的代碼都先執(zhí)行。

6. close callbacks

如果一個(gè)socket或handle被突然關(guān)掉(比如socket.destroy()),close事件將在這個(gè)階段被觸發(fā),否則將通過process.nextTick()觸發(fā)。

1.3 請(qǐng)求對(duì)象

對(duì)于Node中的異步I/O調(diào)用而言,回調(diào)函數(shù)不由開發(fā)者來調(diào)用,從JS發(fā)起調(diào)用到I/O操作完成,存在一個(gè)中間產(chǎn)物,叫請(qǐng)求對(duì)象。
在JS發(fā)起調(diào)用后,JS調(diào)用Node的核心模塊,核心模塊調(diào)用C++內(nèi)建模塊,內(nèi)建模塊通過libuv判斷平臺(tái)并進(jìn)行系統(tǒng)調(diào)用。在進(jìn)行系統(tǒng)調(diào)用時(shí),從JS層傳入的方法和參數(shù)都被封裝在一個(gè)請(qǐng)求對(duì)象中,請(qǐng)求對(duì)象被放在線程池中等待執(zhí)行。JS立即返回繼續(xù)后續(xù)操作。

1.4 執(zhí)行回調(diào)

在線程可用時(shí),線程會(huì)取出請(qǐng)求對(duì)象來執(zhí)行I/O操作,執(zhí)行完后將結(jié)果放在請(qǐng)求對(duì)象中,并歸還線程。
在事件循環(huán)中,I/O觀察者會(huì)不斷的找到線程池中已經(jīng)完成的請(qǐng)求對(duì)象,從中取出回調(diào)函數(shù)和數(shù)據(jù)并執(zhí)行。

跑完當(dāng)前執(zhí)行環(huán)境下能跑完的代碼。每一個(gè)事件消息都被運(yùn)行直到完成為止,在此之前,任何其他事件都不會(huì)被處理。這和C等一些語言不通,它們可能在一個(gè)線程里面,函數(shù)跑著跑著突然停下來,然后其他線程又跑起來了。JS這種機(jī)制的一個(gè)典型的壞處,就是當(dāng)某個(gè)事件處理耗時(shí)過長(zhǎng)時(shí),后面的事件處理都會(huì)被延后,直到這個(gè)事件處理結(jié)束,在瀏覽器環(huán)境中運(yùn)行時(shí),可能會(huì)出現(xiàn)某個(gè)腳本運(yùn)行時(shí)間過長(zhǎng),頁面無響應(yīng)的提示。Node環(huán)境則可能出現(xiàn)大量用戶請(qǐng)求被掛起,不能及時(shí)響應(yīng)的情況。

2. 非I/O的異步API

Node中除了異步I/O之外,還有一些與I/O無關(guān)的異步API,分別是:setTimeout()、setInterval()process.nextTick()、setImmediate(),他們并不是像普通I/O操作那樣真的需要等待事件異步處理結(jié)束再進(jìn)行回調(diào),而是出于定時(shí)或延遲處理的原因才設(shè)計(jì)的。

2.1 setTimeout()setInterval()

這兩個(gè)方法實(shí)現(xiàn)原理與異步I/O相似,只不過不用I/O線程池的參與。
使用它們創(chuàng)建的定時(shí)器會(huì)被放入timers隊(duì)列的一個(gè)紅黑樹中,每次事件循環(huán)執(zhí)行時(shí)會(huì)從相應(yīng)隊(duì)列中取出并判斷是否超過定時(shí)時(shí)間,超過就形成一個(gè)事件,回調(diào)立即執(zhí)行。
所以,和瀏覽器中一樣,這個(gè)并不精確,會(huì)被長(zhǎng)時(shí)間的同步事件阻塞。

值得一提的是,在Node的setTimeout的源碼中:

// Node源碼
  after *= 1; // coalesce to number or NaN
  if (!(after >= 1 && after <= TIMEOUT_MAX)) {
    if (after > TIMEOUT_MAX) {
      process.emitWarning(...);
    }
    after = 1; // schedule on next tick, follows browser behavior
  }

意思是如果沒有設(shè)置這個(gè)after,或者小于1,或者大于TIMEOUT_MAX(2^31-1),都會(huì)被強(qiáng)制設(shè)置為1ms。也就是說setTimeout(xxx,0)其實(shí)等同于setTimeout(xxx,1)。

2.2 setImmediate()

setImmediate()是放在check階段執(zhí)行的,實(shí)際上是一個(gè)特殊的timer,跑在event loop中一個(gè)獨(dú)立的階段。它使用libuv的API來設(shè)定在 poll 階段結(jié)束后立即執(zhí)行回調(diào)。
來看看這個(gè)例子:

setTimeout(function() {
  console.log("setTimeout")
}, 0)
setImmediate(function() {
  console.log("setImmediate")
})                                // 輸出不穩(wěn)定

setTimeout與setImmediate先后入隊(duì)之后,首先進(jìn)入的是timers階段,如果我們的機(jī)器性能一般或者加入了一個(gè)同步長(zhǎng)耗時(shí)操作,那么進(jìn)入timers階段,1ms已經(jīng)過去了,那么setTimeout的回調(diào)會(huì)首先執(zhí)行。
如果沒有到1ms,那么在timers階段的時(shí)候,超時(shí)時(shí)間沒到,setTimeout回調(diào)不執(zhí)行,事件循環(huán)來到了poll階段,這個(gè)時(shí)候隊(duì)列為空,此時(shí)有代碼被setImmediate(),于是先執(zhí)行了setImmediate()的回調(diào)函數(shù),之后在下一個(gè)事件循環(huán)再執(zhí)行setTimemout的回調(diào)函數(shù)。

setTimeout(function() {
  console.log("set timeout")
}, 0)
setImmediate(function() {
  console.log("set Immediate")
})
for (let i = 0; i < 100000; i++) {}           // 可以保證執(zhí)行時(shí)間超過1ms
// 穩(wěn)定輸出: setTimeout    setImmediate

這樣就可以穩(wěn)定輸出了。

再一個(gè)栗子:

const fs = require("fs")
fs.readFile("./filePath.js", (err, data) => {
  setTimeout(() => console.log("setTimeout") , 0)
  setImmediate(() => console.log("setImmediate"))
  console.log("開始了")
  for (let i = 0; i < 100000; i++) {}        
})                                         // 輸出 開始了 setImmediate setTimeout

這里我們就會(huì)發(fā)現(xiàn),setImmediate永遠(yuǎn)先于setTimeout執(zhí)行。
fs.readFile的回調(diào)是在poll階段執(zhí)行的,當(dāng)其回調(diào)執(zhí)行完畢之后,setTimeout與setImmediate先后入了timerscheck的隊(duì)列,繼續(xù)到poll,poll隊(duì)列為空,此時(shí)發(fā)現(xiàn)有setImmediate,于是事件循環(huán)先進(jìn)入check階段執(zhí)行回調(diào),之后在下一個(gè)事件循環(huán)再在timers階段中執(zhí)行setTimeout回調(diào),雖然這個(gè)setTimeout已經(jīng)到了超時(shí)時(shí)間。

再來個(gè)栗子:
同樣的,這段代碼也是一樣的道理:

setTimeout(() => {
    setImmediate(() => console.log("setImmediate") );
    setTimeout(() => console.log("setTimeout") , 0);
}, 0);

以上的代碼在timers階段執(zhí)行外部的setTimeout回調(diào)后,內(nèi)層的setTimeout和setImmediate入隊(duì),之后事件循環(huán)繼續(xù)往后面的階段走,走到poll階段的時(shí)候發(fā)現(xiàn)隊(duì)列為空,此時(shí)有代碼被setImmedate(),所以直接進(jìn)入check階段執(zhí)行響應(yīng)回調(diào)(注意這里沒有去檢測(cè)timers隊(duì)列中是否有成員到達(dá)超時(shí)事件,因?yàn)閟etImmediate()優(yōu)先)。之后在下一個(gè)事件循環(huán)的timers階段中再去執(zhí)行相應(yīng)的回調(diào)。

2.3 process.nextTick()Promise

對(duì)于這兩個(gè),我們可以把它們理解成一個(gè)微任務(wù)。也就是說,它們其實(shí)不屬于事件循環(huán)的一部分。

有時(shí)我們想要立即異步執(zhí)行一個(gè)任務(wù),可能會(huì)使用延時(shí)為0的定時(shí)器,但是這樣開銷很大。我們可以換而使用process.nextTick(),它會(huì)將傳入的回調(diào)放入nextTickQueue隊(duì)列中,下一輪Tick之后取出執(zhí)行,不管事件循環(huán)進(jìn)行到什么地步,都在當(dāng)前執(zhí)行棧的操作結(jié)束的時(shí)候調(diào)用,參見Nodejs官網(wǎng)。

process.nextTick方法指定的回調(diào)函數(shù),總是在當(dāng)前執(zhí)行隊(duì)列的尾部觸發(fā),多個(gè)process.nextTick語句總是一次執(zhí)行完(不管它們是否嵌套),遞歸調(diào)用process.nextTick,將會(huì)沒完沒了,主線程根本不會(huì)去讀取事件隊(duì)列,導(dǎo)致阻塞后續(xù)調(diào)用,直至達(dá)到最大調(diào)用限制。

相比于在定時(shí)器中采用紅黑樹樹的操作時(shí)間復(fù)雜度為0(lg(n)),而process.nextTick()的時(shí)間復(fù)雜度為0(1),相比之下更高效。

來舉一個(gè)復(fù)雜的栗子,這個(gè)栗子搞懂基本上就全部理解了:

setTimeout(() => {
  process.nextTick(() => console.log("nextTick1"))
  
  setTimeout(() => {
    console.log("setTimout1")
    process.nextTick(() => {
      console.log("nextTick2")
      setImmediate(() => console.log("setImmediate1"))
      process.nextTick(() => console.log("nextTick3"))
    })
    setImmediate(() => console.log("setImmediate2"))
    process.nextTick(() => console.log("nextTick4"))
    console.log("sync2")
    setTimeout(() => console.log("setTimout2"), 0)
  }, 0)
  
  console.log("sync1")
}, 0) 
// 輸出: sync1 nextTick1 setTimout1 sync2 nextTick2 nextTick4 nextTick3 setImmediate2 setImmediate1 setTimout2
2.4 結(jié)論

process.nextTick(),效率最高,消費(fèi)資源小,但會(huì)阻塞CPU的后續(xù)調(diào)用;

setTimeout(),精確度不高,可能有延遲執(zhí)行的情況發(fā)生,且因?yàn)閯?dòng)用了紅黑樹,所以消耗資源大;

setImmediate(),消耗的資源小,也不會(huì)造成阻塞,但效率也是最低的。

網(wǎng)上的帖子大多深淺不一,甚至有些前后矛盾,在下的文章都是學(xué)習(xí)過程中的總結(jié),如果發(fā)現(xiàn)錯(cuò)誤,歡迎留言指出~

參考:
Node——異步I/O
Node探秘之事件循環(huán)
Node探秘之事件循環(huán)--setTimeout/setImmediate/process.nextTick的差別
細(xì)說setTimeout/setImmediate/process.nextTick的區(qū)別
深入淺出Nodejs
Node官方文檔
由setTimeout和setImmediate執(zhí)行順序的隨機(jī)性窺探Node的事件循環(huán)機(jī)制
Node.js的event loop及timer/setImmediate/nextTick
Node.js 探秘:初識(shí)單線程的 Node.js | Taobao FED | 淘寶前端團(tuán)隊(duì)
Node.js 事件循環(huán)機(jī)制 - 一像素 - 博客園

PS:歡迎大家關(guān)注我的公眾號(hào)【前端下午茶】,一起加油吧~

另外可以加入「前端下午茶交流群」微信群,長(zhǎng)按識(shí)別下面二維碼即可加我好友,備注加群,我拉你入群~

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

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

相關(guān)文章

  • Node.js設(shè)計(jì)模式》Node.js基本模式

    摘要:回調(diào)函數(shù)是在異步操作完成后傳播其操作結(jié)果的函數(shù),總是用來替代同步操作的返回指令。下面的圖片顯示了中事件循環(huán)過程當(dāng)異步操作完成時(shí),執(zhí)行權(quán)就會(huì)交給這個(gè)異步操作開始的地方,即回調(diào)函數(shù)。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關(guān)注我的專欄,之后的博文將在專欄同步: Enc...

    Seay 評(píng)論0 收藏0
  • JS與Node.js中的事件循環(huán)

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

    abson 評(píng)論0 收藏0
  • Node.js 指南(不要阻塞事件循環(huán)或工作池)

    摘要:為什么要避免阻塞事件循環(huán)和工作池使用少量線程來處理許多客戶端,在中有兩種類型的線程一個(gè)事件循環(huán)又稱主循環(huán)主線程事件線程等,以及一個(gè)工作池也稱為線程池中的個(gè)的池。 不要阻塞事件循環(huán)(或工作池) 你應(yīng)該閱讀這本指南嗎? 如果你編寫的內(nèi)容比簡(jiǎn)短的命令行腳本更復(fù)雜,那么閱讀本文應(yīng)該可以幫助你編寫性能更高、更安全的應(yīng)用程序。 本文檔是在考慮Node服務(wù)器的情況下編寫的,但這些概念也適用于復(fù)雜的N...

    hatlonely 評(píng)論0 收藏0
  • 不要阻塞事件循環(huán)(或工作池)

    摘要:接下來的部分將討論如何確保事件循環(huán)和工作池的公平調(diào)度。不要阻塞事件循環(huán)事件循環(huán)通知每個(gè)新客戶端連接并協(xié)調(diào)對(duì)客戶端的響應(yīng)。 你應(yīng)該閱讀本指南嗎? 如果您編寫比命令行腳本更復(fù)雜的程序,那么閱讀本文可以幫助您編寫性能更高,更安全的應(yīng)用程序。 在編寫本文檔時(shí),主要是基于Node服務(wù)器。但里面的原則也適用于其它復(fù)雜的Node應(yīng)用程序。在沒有特別說明操作系統(tǒng)的情況下,默認(rèn)為L(zhǎng)inux。 TL; D...

    widuu 評(píng)論0 收藏0
  • Node_深入淺出Node

    摘要:簡(jiǎn)介項(xiàng)目命名為就是一個(gè)服務(wù)器單純開發(fā)一個(gè)服務(wù)器的想法,變成構(gòu)建網(wǎng)絡(luò)應(yīng)用的一個(gè)基本框架發(fā)展為一個(gè)強(qiáng)制不共享任何資源的單線程,單進(jìn)程系統(tǒng)。單線程弱點(diǎn)無法利用多核錯(cuò)誤會(huì)引起整個(gè)應(yīng)用退出,應(yīng)用的健壯性大量計(jì)算占用導(dǎo)致無法繼續(xù)調(diào)用異步。 NodeJs簡(jiǎn)介 Ryan Dahl項(xiàng)目命名為:web.js 就是一個(gè)Web服務(wù)器.單純開發(fā)一個(gè)Web服務(wù)器的想法,變成構(gòu)建網(wǎng)絡(luò)應(yīng)用的一個(gè)基本框架.Node發(fā)展...

    shinezejian 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<