Upload
-
View
1.224
Download
3
Embed Size (px)
DESCRIPTION
Citation preview
Asynchronous JavaScriptкак выжить в одном потоке
Немного базового JavaScriptvar object = {}, object1 = new Object, // объекты ar = [100,500], ar = new Array, //массивы func = function(){}, // функции Constr1 = function(name){ this.var1 = name; this.var3 = 5; }, //функции-конструторы date = new Date(), // дата num = 5, num2 = new Number, // число bool = new Boolean, bool2 = true, // логика str = new String, str2 = 'hello', // строка foo; //undefined
var Constr2 = function(){this.var2 = 2; this.var3 = 3;this.do = function(){ console.log(this.var1); };
};Constr2.prototype = { do2: function(){ console.log('Constr1 ' + this.var1); }};Constr1.prototype = new Constr2;
var objConstr = new Constr1('obj'),objConstr1 = new Constr1('obj1');
console.log(objConstr.do()); // >>> "obj";console.log(objConstr1.do()); // >>> "obj1";console.log(objConstr1.do2()); // >>> "Constr1 obj1";console.log(objConstr.var3); // >>> 5console.log(objConstr.var2); // >>> 2
Архитектура браузера
ui
browser engine
rendering engine
networking JS Interpreter XML Parser Display Backend
Data Storage
Архитектура Node.js
OpenSSL c-ares HTTP-парсер
Google V8 libeio/iocp libev
JavaScript Library
C/C++ http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.podhttp://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.podhttps://github.com/joyent/libuvhttp://c-ares.haxx.se/http://www.yuiblog.com/blog/2010/05/20/video-dahl/
libuv
Общая схема работы
Event Loop Операции "ввода/вывода"Очередь сообщений
Блокирование (blocking)
var xhr = new XMLHttpRequest();
xhr.open("GET", "/данные", false);
xhr.onreadystatechange = function(){console.log("данные:", xhr.status);
};
xhr.send();
// немедленная блокировка, после которой в этом же фрейме Event Loop будет вызван // onreadystatechange
Блокирование (blocking)
var cx = 10, xhr = new XMLHttpRequest();
xhr.open("GET", "/данные", false);
xhr.onreadystatechange = function(){console.log("данные: ", xhr.status, " значение cx: ", cx);
};
cx = 20;
xhr.send();
cx = 30;
Выведет:данные: 200 значение cx: 20
Блокирование (blocking)
запрос сервер очнулся и ответил получили ответ
ожидание(ui заблокирован)
ожидание(ui заблокирован)
Не блокирование (Non-blocking)
var cx = 10, xhr = new XMLHttpRequest();
xhr.open("GET", "/данные", true);
xhr.onreadystatechange = function(){console.log("данные: ", xhr.status, " значение cx: ", cx);
};
cx = 20;
xhr.send();
cx = 30;
Выведет:данные: 200 значение cx: 30То есть onreadystatechange не будет выполняться в том же фрейме Event Loop, что и его определение.
Не блокирование (Non-blocking)
запрос сервер очнулся и ответил
получили ответ, вызвали callback
ожиданиено js может делать все что
хочет пока в очередном фрейме не появится сообщение о том что
пришел ответ.ui также восприимчив к
действиям пользователя
ожиданиено js может делать все что
хочет пока в очередном фрейме не появится сообщение о том что
пришел ответ.ui также восприимчив к
действиям пользователя
Шаблоны (design patterns)
Callback
Event
Promise
Deferred
Callbackfunction doSomething( callback ) {
setTimeout( callback, 1000 );}doSomething( function(){
console.log( "something" );} );
function doSomething( msg, callback ) {setTimeout( function(){
callback(msg);}, 1000 );
};doSomething( "anything", function(msg){
console.log( msg );} );
Eventsfunction Events(){
this.events = {};};
Events.prototype = {on: function( event, callback ){
if ( this.events[event] ) this.events[event].push( callback );else this.events[event] = [callback];return this;
},off: function( event, callback ){
if ( this.events[event] && this.events[event].indexOf(callback) != -1 ) {this.events[event].splice( this.events[event].indexOf( callback ) );
}return this;
},trigger: function( event ){
if (this.events[event]) this.events[event].forEach(function( item){item();
});return this;
}};
Eventsfunction callback() {
console.log("wow");}
var events = new Events();
events.on("wow", callback);// ...
events.trigger("wow");
>>> "wow"
events.off("wow", callback);events.trigger("wow");
>>>""
Eventsfunction doSomething(){
this.events = ['success', 'failure'];};doSomething.prototype = new Events();doSomething.prototype.start = function(){
var that = this;setInterval( function(){
that.trigger(that.events[ Math.round(Math.random()) ]);}, 2000 );
}var process = new doSomething;
process.on("success", function(){console.log("success");
}).on("failure", function(){console.log("failure");
});
process.start();>>>success>>>success>>>failure>>>failure>>>success...
Promises
function onPromise(){this.isFulfilled = false;this.isRejected = false;this.isResolved = false;this.result = null;
}
Promise.prototype={then: function( fulfilled, rejected, progressed ){ ... }
}
// обещанное событие, обещанный триггер// меняет свое состояние только один раз// в отличие от событий, которые могут повторяться
http://wiki.commonjs.org/wiki/Promises/A
Promises
promiseXHR('GET', '/данные').then( function() {
console.log("все в порядке");
}, function( error ){
console.log("ошибочка", error);
}, function(){
console.log("процесс пошел")
} );
http://wiki.commonjs.org/wiki/Promises/A
Promises Array
promiseXHR('GET', '/одни данные').then(function(data){
console.log('данные получены', data);
var promises = [ promiseXHR('POST', '/туда отправим', data),promiseXHR('POST', '/сюда отправим', data)
];
when( promises, function(data){console.log('все данные отправлены);
} );
});
http://wiki.commonjs.org/wiki/Promises/A
Deferredvar fn = function() {
var dfd = new Deferred(); // наш объект
var promises = [];
promises.push( async1() ); // асинхронная операция разpromises.push( async2() ); // асинхронная операция дваpromises.push( sync1() ); // синхронная операция разpromises.push( async3() ); // асинхронная операция три
// хотим сделать что-нибудь когда они закончатсяwhen(promises).done(function() {
dfd.resolve(true); }).fail(function(err) {
dfd.reject(err); });
return dfd.promise(); };var promise = fn();promise.then( ... );
WebWorkers// master
var worker = new Worker('я.js');worker.addEventListener('message', function(e) {
console.log('Саша:' + e.data);});
worker.postMessage( 'апельсины' );
worker.postMessage( 'мандарины' );
// worker (я.js)self.addEventListener('message', function(e) {
self.postMessage('Я люблю ' + e.data + '!!!');});
// используем для длительных вычислений// когда они не трогают DOM// например переводим книги :)// часть HTML5// когда передаем объекты, они клонируются..
Node Cluster//script.jsvar cluster = require('cluster');
if (cluster.isMaster) {// плодим воркерыvar coreCount = require('os').cpus().length;for (var i = 0; i < coreCount; i++) {
cluster.fork();}
// слушаем смерть..cluster.on('death', function(worker) {
console.log('Воркер ' + worker.pid + ' умер');});
} else {// умираем если мы воркерprocess.exit();
}
>>> node script.jsВоркер 14230 умерВоркер 14232 умерВоркер 14229 умерВоркер 14221 умер
Библиотеки
Q - https://github.com/ForbesLindesay/QJS
async - https://github.com/caolan/async
step - https://github.com/creationix/step
taskjs - http://taskjs.cometc.
Всем спасибо :)
[email protected]: arudevich