SlideShare a Scribd company logo
Asynchronous JavaScript
    как выжить в одном потоке
Немного базового JavaScript
var 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);        // >>> 5
console.log(objConstr.var2);        // >>> 2
Архитектура браузера

                           ui



                    browser engine
                                             Data Storage



                   rendering engine




 networking   JS Interpreter    XML Parser   Display Backend
Архитектура Node.js
                    JavaScript Library




         OpenSSL        c-ares           HTTP-парсер




        Google V8     libeio/iocp                 libev



                                                        libuv




                                         http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
C/C++                                    http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod
                                         https://github.com/joyent/libuv
                                         http://c-ares.haxx.se/
                                         http://www.yuiblog.com/blog/2010/05/20/video-dahl/
Общая схема работы




Очередь сообщений   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 может делать все что                               ожидание
          хочет пока в очередном                         но js может делать все что
            фрейме не появится                            хочет пока в очередном
            сообщение о том что                             фрейме не появится
                пришел ответ.                               сообщение о том что
           ui также восприимчив к                               пришел ответ.
          действиям пользователя                           ui также восприимчив к
                                                          действиям пользователя
Шаблоны (design patterns)


Callback

Event

Promise

Deferred
Callback
 function 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 );
 } );
Events
function 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;
      }
};
Events
function callback() {
      console.log("wow");
}

var events = new Events();

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

events.trigger("wow");

>>> "wow"



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

>>>""
Events
function 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
Deferred
var 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.js
var 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.com
etc.
Асинхронный JavaScript
Всем спасибо :)




                  rudevich@gmail.com
                  skype: arudevich

More Related Content

What's hot (20)

PDF
FPUG Dzyga presentation
Ivan Filimonov
 
PPTX
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
solit
 
PDF
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Alexey Paznikov
 
PDF
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
Alexey Paznikov
 
PDF
Java 8 puzzlers
Evgeny Borisov
 
PDF
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Noveo
 
PPTX
Григорий Демченко, Универсальный адаптер
Sergey Platonov
 
PDF
RDSDataSource: Чистые тесты на Swift
RAMBLER&Co
 
PDF
JavaDay'14
Kirill Golodnov
 
PDF
RDSDataSource: Promises
RAMBLER&Co
 
PDF
Thread
Alexander Rusin
 
PPTX
Windows Azure and node js
Alex Tumanoff
 
PPTX
Bytecode
Alex Tumanoff
 
PDF
DevConf. Дмитрий Сошников - ECMAScript 6
Dmitry Soshnikov
 
PDF
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Noveo
 
PDF
#2 "Распространённые ошибки в JavaScript" Денис Речкунов
JSib
 
PDF
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
Alexey Paznikov
 
PDF
Decorators' recipes
Yury Yurevich
 
PPTX
Multiprocessor Programming Intro (lecture 3)
Dmitry Tsitelov
 
PDF
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Alexey Paznikov
 
FPUG Dzyga presentation
Ivan Filimonov
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
solit
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
Alexey Paznikov
 
Java 8 puzzlers
Evgeny Borisov
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Noveo
 
Григорий Демченко, Универсальный адаптер
Sergey Platonov
 
RDSDataSource: Чистые тесты на Swift
RAMBLER&Co
 
JavaDay'14
Kirill Golodnov
 
RDSDataSource: Promises
RAMBLER&Co
 
Windows Azure and node js
Alex Tumanoff
 
Bytecode
Alex Tumanoff
 
DevConf. Дмитрий Сошников - ECMAScript 6
Dmitry Soshnikov
 
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Noveo
 
#2 "Распространённые ошибки в JavaScript" Денис Речкунов
JSib
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
Alexey Paznikov
 
Decorators' recipes
Yury Yurevich
 
Multiprocessor Programming Intro (lecture 3)
Dmitry Tsitelov
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Alexey Paznikov
 

Similar to Асинхронный JavaScript (20)

PPT
Подробная презентация JavaScript 6 в 1
Vasya Petrov
 
PDF
JavaScript. Async (in Russian)
Mikhail Davydov
 
PPT
Подробная презентация JavaScript 6 в 1
Vasya Petrov
 
PPT
Web весна 2013 лекция 9
Technopark
 
PPT
Mike ponomarenko java17-fork-v1.2
Alex Tumanoff
 
PDF
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
SmartTools
 
PPT
Web весна 2012 лекция 9
Technopark
 
PDF
JPoint 2016 - Etudes of DIY Java profiler
Anton Arhipov
 
PDF
JavaScript. Loops and functions (in russian)
Mikhail Davydov
 
PPTX
C# Deep Dive
LuxoftTraining
 
PPTX
C sharp deep dive
Sergey Teplyakov
 
PPTX
course js day 2
Georgyi Grigoryev
 
PDF
Михаил Давыдов - JavaScript. Базовые знания
Yandex
 
PDF
Михаил Давыдов - Транспорт, ajax
Yandex
 
PDF
Михаил Давыдов — JavaScript: Базовые знания
Yandex
 
PPTX
функции в Java script
Viktor Andreev
 
PPTX
Funny JS #2
Alexander Konovalov
 
PDF
Обзор ES2015(ES6)
Alex Filatov
 
PDF
Web internship java script
Noveo
 
PPTX
Reactive extensions
Sergey Teplyakov
 
Подробная презентация JavaScript 6 в 1
Vasya Petrov
 
JavaScript. Async (in Russian)
Mikhail Davydov
 
Подробная презентация JavaScript 6 в 1
Vasya Petrov
 
Web весна 2013 лекция 9
Technopark
 
Mike ponomarenko java17-fork-v1.2
Alex Tumanoff
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
SmartTools
 
Web весна 2012 лекция 9
Technopark
 
JPoint 2016 - Etudes of DIY Java profiler
Anton Arhipov
 
JavaScript. Loops and functions (in russian)
Mikhail Davydov
 
C# Deep Dive
LuxoftTraining
 
C sharp deep dive
Sergey Teplyakov
 
course js day 2
Georgyi Grigoryev
 
Михаил Давыдов - JavaScript. Базовые знания
Yandex
 
Михаил Давыдов - Транспорт, ajax
Yandex
 
Михаил Давыдов — JavaScript: Базовые знания
Yandex
 
функции в Java script
Viktor Andreev
 
Funny JS #2
Alexander Konovalov
 
Обзор ES2015(ES6)
Alex Filatov
 
Web internship java script
Noveo
 
Reactive extensions
Sergey Teplyakov
 
Ad

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

  • 1. Asynchronous JavaScript как выжить в одном потоке
  • 2. Немного базового JavaScript var 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); // >>> 5 console.log(objConstr.var2); // >>> 2
  • 3. Архитектура браузера ui browser engine Data Storage rendering engine networking JS Interpreter XML Parser Display Backend
  • 4. Архитектура Node.js JavaScript Library OpenSSL c-ares HTTP-парсер Google V8 libeio/iocp libev libuv http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod C/C++ http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod https://github.com/joyent/libuv http://c-ares.haxx.se/ http://www.yuiblog.com/blog/2010/05/20/video-dahl/
  • 5. Общая схема работы Очередь сообщений Event Loop Операции "ввода/вывода"
  • 6. Блокирование (blocking) var xhr = new XMLHttpRequest(); xhr.open("GET", "/данные", false); xhr.onreadystatechange = function(){ console.log("данные:", xhr.status); }; xhr.send(); // немедленная блокировка, после которой в этом же фрейме Event Loop будет вызван // onreadystatechange
  • 7. Блокирование (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
  • 8. Блокирование (blocking) сервер очнулся и запрос получили ответ ответил ожидание ожидание (ui заблокирован) (ui заблокирован)
  • 9. Не блокирование (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, что и его определение.
  • 10. Не блокирование (Non-blocking) сервер очнулся и получили ответ, запрос ответил вызвали callback ожидание но js может делать все что ожидание хочет пока в очередном но js может делать все что фрейме не появится хочет пока в очередном сообщение о том что фрейме не появится пришел ответ. сообщение о том что ui также восприимчив к пришел ответ. действиям пользователя ui также восприимчив к действиям пользователя
  • 12. Callback function 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 ); } );
  • 13. Events function 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; } };
  • 14. Events function callback() { console.log("wow"); } var events = new Events(); events.on("wow", callback); // ... events.trigger("wow"); >>> "wow" events.off("wow", callback); events.trigger("wow"); >>>""
  • 15. Events function 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 ...
  • 16. 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
  • 17. Promises promiseXHR('GET', '/данные').then( function() { console.log("все в порядке"); }, function( error ){ console.log("ошибочка", error); }, function(){ console.log("процесс пошел") } ); http://wiki.commonjs.org/wiki/Promises/A
  • 18. 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
  • 19. Deferred var 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( ... );
  • 20. 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 // когда передаем объекты, они клонируются..
  • 21. Node Cluster //script.js var 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 умер
  • 22. Библиотеки Q - https://github.com/ForbesLindesay/QJS async - https://github.com/caolan/async step - https://github.com/creationix/step taskjs - http://taskjs.com etc.