The only thing I have done before watching the codeschool course was to download and run the installation file
from https://nodejs.org.
It installs node
and npm
(the package manager for javascript).
You don't actually need to, but it's always nice to see something actually working.
Main points:
- non-blocking
- event loop - checking for events continuously (e.g. request, connection, close)
fs.readFile('/etc/hosts', function(err,contents) { console.log(contents); }); console.log('Doing something else');or equivalently
var callback = function(err,contents) { console.log(contents); }); fs.readFile('/etc/hosts',callback);The Hello World, which you can run with
node hello.js
var http = require('http') http.createServer(function(request,response) { response.writeHead(200, { 'Content-Type': 'text/html' }); response.write("Hello!"); setTimeout(function(){ response.write("I am done."); response.end() }, 5000); }).listen(8080);
Events
Many objects in node emit events, for example, fs.readStream
emits a data
event,
and obviously we can listen for these events. The objects that can emit events inherit from
the EventEmitter class.
We can create custom EventEmitter:
var EventEmitter = require('events').EventEmitter; var logger = new EventEmitter();If you want to listen for error events:
logger.on('error',function(message){ console.log('Error: ' + message); });And to trigger the event:
logger.emit('error','An error');
In fact, earlier, when we called http.createServer(function(request,response) {...})
,
this returns a http.Server
object, which is an EventEmitter,
set to listen for request
events (it is all in the documentation for node.js).
It is possible to write it this way:
var server = http.createServer(); server.on('request', function(request,response}{ response.writeHead(200); response.write("Hello, this is dog"); response.end(); });which is how you can explicitly bind several listeners on the same object. Actually, you can listen to an event more than once:
var http = require('http'); var server = http.createServer(); server.on('request', function(request, response) { response.writeHead(200); response.write("Hello, this is dog"); response.end(); }); server.on('request', function(request, response) { console.log("New request coming in..."); }); server.on('close', function(){ console.log("Closing down the server..."); }); server.listen(8080);In the code above, whenever a request event happens, two things happen: send a response and write to console.
Streams
Streams is about how data is transferred back and forth. Streams can be readable, writable, or both. For example,
in the arguments for http.createServer
, request
is a readable stream, response
is a writable stream. These streams are kept open until we close the connection.
How do you read from a stream (e.g. how do you read request
?). The request
object is an EventEmitter,
and it emits two events: 'readable', when the server can start reading the data, and 'end', when the client finishes uploading
the data. Here is an example code:
http.createServer(function(request,response){ response.writeHead(200) request.on('readable',function(){ var chunk = null; while (null !== (chunk = request.read())) { response.write(chunk); } }); request.on('end'), function() { response.end(); }); }).listen(8080);(the .write function implicitly does toString()). However, there is an even faster method, using pipe:
http.createServer(function(request,response) { response.writeHead(200); request.pipe(response); }).listen(8080);
How is that useful? Well, the second main example is about reading and writing file:
var fs = require('fs'); // require the filesystem module var file = fs.createReadStream("readme.md"); var newfile = fs.createWriteStream("readme_copy.md"); file.pipe(newFile);You can for example do
request.pipe(newfile)
, and when you
for example do
$ curl --upload-file readme.md localhost:8080it will upload readme.md to newfile. Here is a complete implementation of file upload with progress update:
http.createServer(function(request,response){ var newFile = fs.createWriteStream("readme_copy.md"); var fileBytes = request.headers['content-length']; var uploadedBytes = 0; request.on('readable', function() { var chunk = null; while(null !== (chunk = request.read())) { uploadedBytes += chunk.length; var progress = (uploadedBytes / fileBytes)*100; response.write("progress: " + parseInt(progress,10) + "%\n"); } }); request.pipe(newFile); }).listen(8080);To do list: play around with http://gulpjs.com.
No comments:
Post a Comment