Blocking & Non-Blocking
Nodejs 為事件觸發的單一執行緒,不像 Apache + PHP 會自動開一個 Thread 去接每一個 Request。 Blocking Code 示範 (程式碼另有 index.js 請參照重新踏入網頁開發 (4) - Dependency injection)
- route.js
function start_requset_handle () { console.log("Start request."); // Sleep for 10 seconds function sleep(milliSeconds) { var startTime = new Date().getTime(); while (new Date().getTime() < startTime + milliSeconds); } sleep(10000); } function upload_requset_handle () { console.log("Upload request."); } function requset_handler (url) { var handle = {}; handle['/'] = start_requset_handle; handle['/start'] = start_requset_handle; handle['/upload'] = upload_requset_handle; if (typeof handle[url] === 'function') { handle[url](); } else { console.log("No request handler found for " + url); } } export function route(url) { requset_handler(url); }
- server.js
import http from 'http' import url from 'url' export function serverStart(route) { function onRequest(request, response) { var path_name = url.parse(request.url).pathname; console.log("Request for " + path_name + " received"); // Routing function route(path_name); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World.\n"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started..."); }
這裡先用 requset_handler() 這 function 去應對 2 種 url 的 request。client 端 request http://localhost:8888/start 會等 10 秒才回覆 Hello World.,request http://localhost:8888/upload 則立即回覆。因為 nodejs 為單一執行緒,如果有人先 request start, 後面即使是 request upload 也要跟著等 10 秒。
Non-Blocking Code 示範 (程式碼另有 index.js 請參照重新踏入網頁開發 (4) - Dependency injection)
- route.js
import { exec } from 'child_process'; function start_requset_handle (response) { console.log("Start request."); var content = "empty\n"; exec("ls -alh", function (error, stdout, stderr) { content = stdout; response.writeHead(200, {"Content-Type": "text/plain"}); response.write(content); response.end(); }); // 放在外面會讓 server 直接回 empty // response.writeHead(200, {"Content-Type": "text/plain"}); // response.write(content); // response.end(); } function upload_requset_handle (response) { console.log("Upload request."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Uploading...\n"); response.end(); } function requset_handler (url, response) { var handle = {}; handle['/'] = start_requset_handle; handle['/start'] = start_requset_handle; handle['/upload'] = upload_requset_handle; if (typeof handle[url] === 'function') { handle[url](response); } else { console.log("No request handler found for " + url); } } export function route(url, response) { requset_handler(url, response); }
- server.js
import http from 'http' import url from 'url' export function serverStart(route) { function onRequest(request, response) { var path_name = url.parse(request.url).pathname; console.log("Request for " + path_name + " received"); // Routing function route(path_name, response); } http.createServer(onRequest).listen(8888); console.log("Server has started..."); }
import nodejs 內建的 child_process,解決了問題。傳 response 進去是為了讓 request 處理完再做回覆。
上一篇 :
下一篇 :
參考資料 :