setTimeout(function(){console.log('b')},0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function a(){
console.log('a')
b()
}
function b(){
setTimeout(function(){console.log('b')},0)
c()
}
function c(){
console.log('c')
}
a()
setTimeout(cb, milliseconds)
: exécute la fonction cb
après
que le délai soit écoulé
L'environnement d'exécution javascript (node ou navigateur) fournit:
while (atLeastOneEventIsQueued) {
1
2
3
4
runYourScript();
while (atLeastOneEventIsQueued) {
fireNextQueuedEvent();
};
Remarque : chaque code exécuté peut à son tour différer des actions …
Les actions différées sont définies de la manière suivante:
Les évènements signalés dépendent de l'environnement d'exécution :
Certains évèrements se retrouvent sur les 2 environnements :
setTimeout
, setInterval
La gestion des évènements est entièrement sous le contrôle de l'environnement.
request('http://gamba.enseeiht.fr/cours_javascript', callback);
1
2
3
4
5
6
7
8
var request = require('request')
var callback = function(error, response, body) {
console.log(body);
}
// rajout d'un message (event, callback)
request('http://gamba.enseeiht.fr/cours_javascript', callback);
console.log('Done!');
callback
Résultat : «Done!» s'affiche d'abord, puis l'EventLoop attend un évènement. Quand l'évènement arrive (ici résultat de request), la fonction callback est exécutée.
epoll
linux, kqueue
*BSD/OS X,
/dev/poll
Solaris, select
POSIX).
node.js est donc à conseiller sur des programmes passant du temps sur les I/O et peu sur le calcul. Par exemple : une application web, mais pas seulement.
fs.readFile('/tmp/test', consomme_fichier)
1
2
3
4
5
6
7
function consomme_fichier(err, data){
if (err) { throw err }
console.log(data)
}
fs.readFile('/tmp/test', consomme_fichier)
console.log("contenu du fichier: ")
Extrait :
events
: require('events').EventEmitter
emitter.addListener(event, listener)
(ou emitter.on
) :
C'est la fonctionnalité principale : on ajoute un écouteur à un évènement.
event
: une chaîne de caractèresserver.on('connection', function(stream) {
1
2
3
server.on('connection', function(stream) {
console.log('new connection');
}
emitter.emit(event, [arg1], [arg2], […]
: exécute tous les écouteurs de
l'évènement event
.
Attention : si vous appeler emitter.emit
, l'appel sera synchrone et réalisé
immédiatement. Pour une gestion asynchrone, emit
est utilisé par du code
géré par l'environnement d'exécution pour signaler un évènement externe (fin de lecture
d'un fichier par exemple)
La documentation d'un classe implémentant EventEmitter
est donc
essentiellement une suite de :
event: handler(arg1, arg2, …)
: le nom de l'évènement, et la signature de
la fonction qui le gère.
L'interface Stream permet à node.js de traiter de manière uniforme tous les flux comme
des EventEmitter
.
Les flux peuvent être en lecture, écriture, ou les 2 (duplex).
stream.Readable
stream.read()
Évènements gérés :
readable
: soulevé quand des données peuvent être luesfunction(chunk) {…}
: passe en flowing mode. console.log('got %d bytes of data', chunk.length);
1
2
3
4
var readable = getReadableStreamSomehow();
readable.on('data', function(chunk) {
console.log('got %d bytes of data', chunk.length);
});
Méthodes:
readable.setEncoding(encoding)
:
readable.setEncoding('utf8');
readable.read([size])
stream.Writable
writable.write(chunk, [encoding], [callback])
true
signifie que les données écrites ont été
traitées.
callback : appelé après que les données aient été lu du buffer
chunk
.
event drain
: si writable.write(chunk)
retourne
false
, drain
signale quand l'écriture est de nouveau
possible.
writable.end()
: signale que l'écriture est finie, émet l'évènement
finish
.
http.IncomingMessage
Readable Stream
http.ServerResponse
Writable Stream
// server is an [EventEmmiter](http://nodejs.org/api/events.html#events_class_events_eventemitter)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var http = require('http');
var server = http.createServer();
var util = require('util');
// server is an [EventEmmiter](http://nodejs.org/api/events.html#events_class_events_eventemitter)
// Events :
// request : when a request is received : function(request, response) {}
// connection: function(socket){}
// close : function(){}
server.addListener('request', handle);
function handle(req, res) {
var message = "request received:\n";
var url = require('url').parse(req.url, true);
var body = '';
message += "method: " + req.method + "\n";
message += "path: " + url.pathname + "\n";
message += "query: " + util.inspect(url.query, {color: true}) + "\n";
message += "headers: " + util.inspect(req.headers, {color: true}) + "\n";
message += "body: \n";
req.on('data', function(chunk){
body += chunk;
console.log("---\n" + chunk +"---\n");
});
req.on('end', function(){
message += body
console.log(message);
res.writeHead(200, {
'Content-Length': Buffer.byteLength(message),
'Content-Type': 'text/plain'
});
res.write(message, 'utf8'); // utf8 is the default
res.end();
});
}
server.listen(8000);
console.log("listening on port 8000");
node http.js
curl -X GET -H 'MyHeader: space/and_beyond' http://localhost:8000/toto
curl -X PUT -H 'Content-Type:application/json' --data "{toto:titi, a: 42}" http://localhost:8000/putit
Hello Word
quand
une requête de GET /hello
est demandée.
Lire d'un fichier : Readable Stream. Écrire dans la réponse http : Writable Stream.
Combinez
fs.createReadStream
avec res.write
/res.end
en utilisant
readable.pipe
12/12
#