Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Noder eyes for frontend guys

948 views

Published on

my s

Published in: Technology
  • Login to see the comments

Noder eyes for frontend guys

  1. 1. Noder eyes for frontend guys by Fillano
  2. 2. 先說聲抱歉 Orz
  3. 3. 關於題目● 源自 "Queer eyes for straight guys"● 澄清一下 ○ 寫node.js不表示比較厲害,只是希望能讓熟悉瀏覽器 的Javascript coder可以知道進入node.js需要的知識跟 常見的難點 ○ Im not queer, but I do have some friends.● 另外...
  4. 4. 這個投影片不會講到● node.js的教學● 各個module怎麼用的詳細說明● 怎麼做出XXX(忍不住還是會...)
  5. 5. 這個投影片會專注在● 寫node.js程式需要的關鍵知識● 如何開始寫node.js程式的一些提示
  6. 6. 開始吧...
  7. 7. window物件在哪?● 可能情境:裝完node.js,進入shell,不知道有什 麼可以使用● 在瀏覽器中,一切都可以從window物件開始, 那在node.js中,有什麼相同的東西?● 這要從Javascript的基本特性談起...
  8. 8. Javascrip基本:依賴於host環境● 核心物件之外,所有能用的功能,都放在Global 中● 在browser中,Global就是window物件● 在node.js中,Global就是global物件● 檢查一下:test001.js● 有三個同名的物件,實際上都是global物件● 檢查一下:test001a.js● 但是呢...
  9. 9. node.js對於Global做了一點調整● 操作global物件,可以反應在global scope● 但是直接操作global scope,並不會影響到 global物件● 這跟在瀏覽器環境中的行為不太一樣● 檢查一下:test001b.js● 在瀏覽器中:test794.html● 那麼...
  10. 10. global物件到底能做什麼● 只有: ○ 操作TypedArray需要的相關物件 ○ process物件 ○ Buffer constructor ○ setTimeout/setInterval相關函數 ○ console物件,用來作stdio● 檢查一下:test002.js● 接下來咧?好像沒啥東西...
  11. 11. 那其他功能怎麼辦?● 其實還有require這個核心函數,可以用它來載 入模組● 檢查一下:test003.js● 後面還會詳細解釋一下模組的運作● 了解了global物件,再看一個偶爾會有人問的 問題...
  12. 12. 我可以使用jQuery嗎?● 通常我會想:別傻了,你在寫伺服器程式● 不是沒有解(JSDom...)● 但除了做蜘蛛,通常不會用到● 下一個問題也有不少人問...就是...
  13. 13. 什麼?單一執行緒?● 用關鍵字應該可以找到不少這方面的討論● 不過這個問題說來話長...下一頁繼續
  14. 14. 其實,single thread是寫Javascript的必備知識● 參考 ○ Resig: How JavaScript Timers Work ○ Zakas: Professional Javascript for Web Developers: p. 598 Advanced Timers ○ Opera: Timing and Synchronization in Javascript ○ HTML5: HTML5 Spec - 6.1.4 Event loops ○ YDN: Understanding event loops and writing great code for Node.js
  15. 15. 歸納起來,就是● 不論是非同步的事件、timer、UI parsing等● browser所載入的每個網頁,你寫的Javascript 都是在一個thread裡面跑● 在node.js也是這樣
  16. 16. 所以,Javascript到底怎麼跑?● 可以把Javascript的執行過程想像成 a. 執行top most的程式碼(主要是global scope,以及此時 執行的函數) b. 進入event loop c. 一有有事件程式放進event queue,event loop就會取出 來執行 ■ 由timer觸發的,不會在時間到之前執行,但是可能 會更慢 ■ 由event觸發的,就是儘快執行● node.js的特異功能 a. process.nextTick():會盡量排在event queue前面讓他 可以先執行,而不是從後面填入
  17. 17. 這不是例外,但其實你有機會碰到別的thread● 在網頁端: ○ frame/iframe ○ web worker● 在node.js ○ sub process ○ threads-a-gogo模組(這是真的thread,只能透過 message溝通,目前還無法做什麼事)● 測試:test644.html(WebWorker的global跟網頁中完全不同)
  18. 18. 在底層,還有更多東西必須使用thread● 寫Javascript不會直接接觸...但是在機制上 ○ 瀏覽器:XMLHttpRequest底層 ■ onreadystatuschange ● 網路I/O在另外一個thread跑,根據處理的狀態 變化,才把叫onreadystatuschange事件處理函 數塞進event queue ○ node.js:I/O底層 ■ fs.read ■ fs.write● 所以,single thread是對Javascript Coder必須的概念,但是 引擎實作並不是這樣
  19. 19. single thread的方便性● 同一時間不會執行兩段程式 ○ 沒有race ○ 不需要lock ○ 寫非同步比較簡單● 但是我們寫的code可能會...
  20. 20. 程式寫壞了,就全部塞住● 這不論在瀏覽器或伺服器端都一樣,某個 function中的程式卡住(ex. 無窮迴圈),就全部 卡住了● 在node.js,沒有catch到的exception,會讓程式 exit,但是沒exception照樣可能卡著(ex. 無窮 迴圈)● 就算沒卡住...
  21. 21. 程式寫不好,伺服器反應就全部變慢● 沒那麼糟,但是不優● 但是有時...就是得做花時間的事情● 有什麼辦法?
  22. 22. 所以有些事可以慢點做● 程式打死結(ex. 無窮迴圈),是一定沒救● 但是某個事件處理程式跑太久,還是會阻礙別 人● 在Browser跟node.js解法都一樣,make it async by do something later● 使用setTimeout()/setInterval()● 使用process.nextTick()● 在single thread中跑的程式,就像DOS時代的合 作式多工...
  23. 23. 不過async會讓邏輯更複雜XD● 這在node.js常碰到,建議要習慣用async的邏 輯來思考事情● 有一些解決方法,容後再述● 另外的問題是,程式都在同一個thread跑喔, 可是...
  24. 24. node.js在伺服器端執行耶!?● 這不是瀏覽器...● 如果只有單核心,再多thread也只會用到一個 cpu核心的資源,就沒差● 可是,我的伺服器有四路八核心cpu,總共有32 核心,但是node只會用到一個...● 解法在v0.6.x之後出現...容後再敘● 有了一些基本認識,可以開始coding了...不過一 頭鑽進去會發現...
  25. 25. hello world...然後我要做什麼?● hello world總是很美好XD● 但是很遺憾...http模組幫你做的事情不多● 因為他沒做,所以你需要基本的http知識 ○ http request ○ http headers ○ session相關 ■ cookie header ■ setcookie header ■ 怎麼做出伺服器端session ○ MIME ○ ...● 另外,沒人幫你map靜態檔案● ...
  26. 26. 對於新手來說,單靠node.js核心模組是不可能寫出功能完整的伺服器Orz● 想像一下,你要用幾個基本的物件做出apache httpd伺服器,工程很大的...● 我自己為例,之前參加ITHelp鐵人賽,花了一 個月還只有架構● 所以要快的話,還是得先靠第三方模組 ○ Connect middleware可以做基礎 ○ 一些Web Framework ■ Express ■ others ● Meteor ● Mojito ● ...● 那要怎樣找模組?...
  27. 27. 模組管理工具:NPM● NPM(Node Package Manager)● 原本是第三方的解決方案● 目前已納入node.js的binary distribution中● 怎麼找模組? ○ `npm search KEYWORD` (常會用完記憶體) ○ http://search.npmjs.org/ (官網,但是很慢) ○ https://github. com/joyent/node/wiki/modules (這是分門別類的目 錄,但是更新可能比較慢) ○ nipster (很快,而且用評分排序)
  28. 28. node怎麼找到模組● 之前測試過...test003.js可以看到一些線索● 模組預設搜尋路徑 ○ 目前工作目錄下的node_modules目錄 ○ require.main.paths陣列中的目錄● npm list -g顯示的路徑加上node_modules ○ 預設 ■ UNIX: /usr/lib or /usr/local/lib ■ Windows: %APPDATAnpm● 用npm安裝/管理模組會使用的路徑 ○ 沒有加-g:目前路徑 ○ 有加-g:npm list -g顯示的路徑
  29. 29. 想使用global module● 如果(不建議)希望可以直接使用● 需要設定NODE_PATH環境變數,指向npm list -g使用的模組目錄 + node_modules
  30. 30. 使用了模組...怎麼維護相依性?● 我們使用npm,npm使用package.json檔● package.json(模組根目錄中) ○ 不管寫不寫模組,最好都知道裡面定義的各個欄位 ○ 跟執行相關 ■ 定義模組的entry檔案 ■ 定義模組的相依性● 許多node.js hosting service,都支援package. json,在deploy的過程中,會幫你把相依的模組 裝好● 參考: ○ http://package.json.nodejitsu.com/ ○ npm help json
  31. 31. node.js的模組載入機制與注意事項● require是同步執行的 ○ 呼叫require時,要等到模組載入完畢,才會執行下一行 程式● module是在沙箱中跑的 ○ 所以,模組裡面沒有辦法動到主程式 ○ 主程式要用到的東西,全部都要export(module.exports 或exports)● 執行過一次require後,模組就會被cache起來 ○ 所以,修改過的module,要重新啟動程式才會有作用
  32. 32. 但是我希望程式可以在修改後不停機自動apply耶...● 最好讓host服務替你做,省功夫● 手動做的話,可以考慮使用cluster● 驗證一下:test005.js ○ 由於每個worker都是獨立的process,kill掉再重新執 行,就會使用新的程式了 ○ 缺點是:master無法更新... ○ 仔細想一想:如果把worker內的程式寫成模組來載入, 然後master用fs.watch模組的目錄,然後每次deploy 都更新這個模組...其實就類似hosting的做法了
  33. 33. 但是,我需要AMD的話怎麼辦?● 參考:require.js● 其實,你可以自己做● 例如:node-amd-loader● 重點: ○ node只提供了核心模組 ○ 沒人告訴你其他的不能自己做 ○ 忘記那些爭論吧(阿?有爭論?)
  34. 34. 我需要物件導向嗎?● node.js常用的作法: ○ 使用util.inherits(),這是給constructor來用的喔 ○ 最常使用的地方:需要使用到事件機制,就要繼承 EventEmitter● 其他...就任意...Javascript有多種作法● 參考一下良葛格的意見 ○ 程式語言的特性本質(三)-從消弭重複性看封裝、繼 承、多型● 再來是另一個常被問到的問題...
  35. 35. 有辦法避開callback地獄嗎?● 這是無法避免的,請練習async的邏輯思考● 可以透過適當的調整來改善 ○ 取代匿名函數callback(這是一個過程,這樣還可以方 便單元測試) ■ 改用非匿名的函數 ■ 進一步利用模組帶入這個函數 ○ 利用flow control來管理函數,讓你可以控制數個函數 執行過程的關係,例如某幾個函數要順序執行、某幾個 函數要平行執行等
  36. 36. 有辦法避開非同步地獄嗎?● 同樣難以避免● 而且,在執行上有時會碰到邏輯上的困難點● 解決方式如前述● 那麼...
  37. 37. 什麼是flow control?● 函數在Javascript是一等公民,所以可以用函 數來處理函數● 測試一下:test006.js ○ 執行三個函數 ○ 全部執行完畢,才執行某個函數來處理結果● 除了使用flow control,要能使用flow control的 函數,通常要改寫成cps的形式● cps (continuation passing style) ○ 簡單地說就是傳入一個callback ○ 在函數結束時(可能不只一處),呼叫這個callback,有 返回值時,需要把返回值傳給它
  38. 38. 關於flow control的好文章● Tim Caswell ○ Control Flow in Node ○ Control Flow in Node Part II ○ Control Flow in Node Part III● Mixus tech blog ○ Essential Node.js patterns and snippets ○ 我的例子用這個改的,因為邏輯最簡單● 一些模組 ○ https://github.com/creationix/step ○ https://github.com/caolan/async ○ https://github.com/laverdet/node-fibers
  39. 39. 另外一個讓程式碼更有結構又乾淨的方式● CoffeeScript● ...我沒在用,我已經太習慣Javascript了XD● 早上有人講這個喔(高見龍 / 龍哥)● 另外一個寫伺服器會發現的,是關於...
  40. 40. gloal variables● 以http server為例,每個request是一個事件● 要維護cross request的狀態(ex. session),用 global variable就可以做到(其實不一定,要看 事件處理函數定義的位置)● 不過當需要scale的時候,這個作法就會出問題 (ex. cluster)● 所以,共享的狀態,儘量用外部實現比較好 (memcache, mongodb etc.)● 好,終於要來看怎麼解決無法利用多核心cpu 的...
  41. 41. cluster模組● since v0.6.x● 解決single thread無法充分利用多核心的系統 優勢的問題● 使用多個sub process,共享同一個port● master/worker之間,透過message來溝通● 測試一下?(之前測過了XD)
  42. 42. cluster不是真的scaling● 不要被cluster這個名字拐了● 真正要scaling,請使用reverse proxy,例如: ○ nginx ○ node-proxy模組 (效能不如nginx)● 基本上,不論使用怎樣的程式語言,大多數伺 服器都可以這樣scale● 另外,許多PAAS(node.js hosting)會提供方案及 工具來做
  43. 43. 我要怎樣debug?● 建議把邏輯集中到function,放進module,做單 元測試(這是基本的refactoring)● 簡單的邏輯bug,用console.log、console.dir就可 以解決● 如果需要做profiling、找出memory leak,再來使 用debug工具,例如 ○ Using Eclipse as Node Applications Debugger ○ other solutions: node-inpector, ndb etc.
  44. 44. 有什麼hosting服務嗎?● 有許多廠商提供這方面的服務 ○ Joyent (MiCloud) ○ Heroku ○ Nodejitsu ○ Nodester ○ Azure ○ more...● 選擇重點 ○ 基本管理工具 ○ deploy方式 ○ 擴充方案
  45. 45. 兩三事代替總結● 這些主題,有很多是在nodejs group上常見的● 而且,裡面有些東西是火藥庫● node.js開發team的目標,是一個精簡而可靠 的核心,所以會放棄很多用第三方模組就可以 做到的功能● 有需求的地方,就是可以自己插手的地方,畢 竟node.js還很年輕● 後面某一場,Ben會分享他為什麼要開發自己 的framework,大家可以聽一聽他的心得
  46. 46. Q&A
  47. 47. 我最近的出沒地點● 我的Facebook● 我的噗浪● facebook Javascript.tw group● facebook nodejs.tw group● facebook PHP 台灣 group● Zen of Friends讀書會以及Web Dev Party● 我的部落格 (自從用噗浪以後就少出沒了)● 歡迎來交朋友...
  48. 48. The End

×