Изложение моего понимания нескольких основных принципов платформы Node.js на простых примерах. Понимание - это процесс. В моем случае процесс сопровождается чтением "Professional Node.js. Building Javascript Based Scalable Software" by Pedro Teixeira.
Неблокирующий код.
Рассмотрим на примере двух HTML-страниц.
Blocking:
Non-blocking:
Замыкания.
В Node (который суть JavaScript) очень часто применяются функции обратного вызова, поэтому использовать контекст выполнения очень удобно.
На примере HTML-страницы выглядит примерно так:
Предотвратить засорение глобального объекта можно следующим образом:
Модули.
В Node используется система организации модулей CommonJS, что позволяет избежать проблем, связанных с глобальным объектом, присущих браузерному JavaScript.
mymodule_require.js:
Callback.
Функции обратного вызова - один из основных паттернов Node. Для примера прочитаем содержимое файла.
Синхронно, fssync.js:
Асинхронно, fsasync.js:
Event emitter.
Объект, который (в соответствии с названием) эмитирует события. Один из основных паттернов Node.
event_emitter.js:
p.s. Node.js - это интересно.
Неблокирующий код.
Рассмотрим на примере двух HTML-страниц.
Blocking:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Blocking</title> </head> <body> <script type="text/javascript"> var d = new Date(); var n = 1000000000; document.body.appendChild(document.createTextNode('Посчитаем до ' + n)); var i = 0; while (i < n) i++; document.body.appendChild(document.createElement('br')); document.body.appendChild(document.createTextNode('i = ' + i)); document.body.appendChild(document.createElement('br')); var t = new Date() - d; document.body.appendChild(document.createTextNode('t = ' + String(t) + ' ms')); </script> </body> </html>
Non-blocking:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Non-blocking</title> </head> <body> <script type="text/javascript"> var d = new Date(); var n = 1000000000; document.body.appendChild(document.createTextNode('Посчитаем до ' + n)); setTimeout(function() { var i = 0; while (i < n) i++; document.body.appendChild(document.createElement('br')); document.body.appendChild(document.createTextNode('i = ' + i)); }, 0); document.body.appendChild(document.createElement('br')); var t = new Date() - d; document.body.appendChild(document.createTextNode('t = ' + String(t) + ' ms')); </script> </body> </html>
Замыкания.
В Node (который суть JavaScript) очень часто применяются функции обратного вызова, поэтому использовать контекст выполнения очень удобно.
На примере HTML-страницы выглядит примерно так:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Closure</title> </head> <body> <div id="sq" style="width: 400px; height: 400px; background-color:#ffff00;"></div> <script type="text/javascript"> var i = 1; var sq = document.getElementById('sq'); function step() { var h = i.toString(16); sq.style.backgroundColor = "#ffff" + h + h; if (i < 15) { i++; setTimeout(step, 300); } } setTimeout(step, 300); </script> </body> </html>
Предотвратить засорение глобального объекта можно следующим образом:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Closure - Non-polluting</title> </head> <body> <div id="sq" style="width: 400px; height: 400px; background-color:#ffff00;"></div> <script type="text/javascript"> (function() { var i = 1; var sq = document.getElementById('sq'); function step() { var h = i.toString(16); sq.style.backgroundColor = "#ffff" + h + h; if (i < 15) { i++; setTimeout(step, 300); } } setTimeout(step, 300); })(); </script> </body> </html>
Модули.
В Node используется система организации модулей CommonJS, что позволяет избежать проблем, связанных с глобальным объектом, присущих браузерному JavaScript.
mymodule.js:
exports.hello = function() { console.log('Hello!'); }
mymodule_require.js:
require('./mymodule').hello();
Callback.
Функции обратного вызова - один из основных паттернов Node. Для примера прочитаем содержимое файла.
Синхронно, fssync.js:
var fs = require('fs'); console.log(fs.readFileSync('mymodule.js').toString());
Асинхронно, fsasync.js:
var fs = require('fs'); fs.readFile('mymodule.js', function(err, content) { if (err) throw err; console.log(content.toString()); });
Event emitter.
Объект, который (в соответствии с названием) эмитирует события. Один из основных паттернов Node.
event_emitter.js:
var util = require('util'), EventEmitter = require('events').EventEmitter; // объект event emitter var Ticker = function() { var self = this; setInterval(function() { self.emit('tick'); }, 1000); }; //Ticker.prototype = EventEmitter; // класс Ticker наследует от класса EventEmitter, таким образом // методы прототипа EventEmitter становятся доступны для класса Ticker util.inherits(Ticker, EventEmitter); // объект event listener var ticker = new Ticker(); // можно использовать .addListener, но .on - короче //ticker.addListener("tick", function() { ticker.on("tick", function() { console.log("tick"); });
p.s. Node.js - это интересно.
Комментариев нет:
Отправить комментарий
Комментарий будет опубликован после модерации