24
Asynchronous JavaScript как выжить в одном потоке

Асинхронный JavaScript

  • Upload
    -

  • View
    1.224

  • Download
    3

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Асинхронный JavaScript

Asynchronous JavaScriptкак выжить в одном потоке

Page 2: Асинхронный 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

Page 3: Асинхронный JavaScript

Архитектура браузера

ui

browser engine

rendering engine

networking JS Interpreter XML Parser Display Backend

Data Storage

Page 4: Асинхронный JavaScript

Архитектура 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

Page 5: Асинхронный JavaScript

Общая схема работы

Event Loop Операции "ввода/вывода"Очередь сообщений

Page 6: Асинхронный JavaScript

Блокирование (blocking)

var xhr = new XMLHttpRequest();

xhr.open("GET", "/данные", false);

xhr.onreadystatechange = function(){console.log("данные:", xhr.status);

};

xhr.send();

// немедленная блокировка, после которой в этом же фрейме Event Loop будет вызван // onreadystatechange

Page 7: Асинхронный JavaScript

Блокирование (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

Page 8: Асинхронный JavaScript

Блокирование (blocking)

запрос сервер очнулся и ответил получили ответ

ожидание(ui заблокирован)

ожидание(ui заблокирован)

Page 9: Асинхронный JavaScript

Не блокирование (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, что и его определение.

Page 10: Асинхронный JavaScript

Не блокирование (Non-blocking)

запрос сервер очнулся и ответил

получили ответ, вызвали callback

ожиданиено js может делать все что

хочет пока в очередном фрейме не появится сообщение о том что

пришел ответ.ui также восприимчив к

действиям пользователя

ожиданиено js может делать все что

хочет пока в очередном фрейме не появится сообщение о том что

пришел ответ.ui также восприимчив к

действиям пользователя

Page 11: Асинхронный JavaScript

Шаблоны (design patterns)

Callback

Event

Promise

Deferred

Page 12: Асинхронный JavaScript

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 );} );

Page 13: Асинхронный JavaScript

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;

}};

Page 14: Асинхронный JavaScript

Eventsfunction callback() {

console.log("wow");}

var events = new Events();

events.on("wow", callback);// ...

events.trigger("wow");

>>> "wow"

events.off("wow", callback);events.trigger("wow");

>>>""

Page 15: Асинхронный JavaScript

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...

Page 16: Асинхронный JavaScript

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

Page 17: Асинхронный JavaScript

Promises

promiseXHR('GET', '/данные').then( function() {

console.log("все в порядке");

}, function( error ){

console.log("ошибочка", error);

}, function(){

console.log("процесс пошел")

} );

http://wiki.commonjs.org/wiki/Promises/A

Page 18: Асинхронный JavaScript

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

Page 19: Асинхронный JavaScript

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( ... );

Page 20: Асинхронный JavaScript

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// когда передаем объекты, они клонируются..

Page 21: Асинхронный JavaScript

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 умер

Page 22: Асинхронный JavaScript

Библиотеки

Q - https://github.com/ForbesLindesay/QJS

async - https://github.com/caolan/async

step - https://github.com/creationix/step

taskjs - http://taskjs.cometc.

Page 23: Асинхронный JavaScript
Page 24: Асинхронный JavaScript

Всем спасибо :)

[email protected]: arudevich