Модель совпадения и цикл событий. Асинхронное выполнение, функции как колбэки, Promise Masters Academy, 2018
1. Стэк (stack) контекстов выполнения функций программы 2. Куча (heap) - неструктурированная область памяти, для хранения объектов 3. Очередь событий (queue) - список событий, подлежащих обработке вследствие выполнения асинхронных операций
and more...
function foo(x) { return 5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15); “First in - last out” principle
function foo(x) { return 5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
function foo(x) { return 5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
function foo(x) { return 5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
function foo(x) { return 5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
function foo(x) { return 5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
function foo(x) { return 5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
setTimeout(function() { console.log(‘timeout 500 complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15); Output: // 82 // timeout 0 complete // timeout 500 complete
Callbacks setTimeout(() => { console.log(‘Hello World!’) }, 1000); ajax(‘http://someurl.com’, ‘GET’, data => console.log(data)) // ajax in some http lib element.addEventListener(‘click’, evt => console.log(‘element clicked!!!’))
Callback Hell button.addEventListener(‘click’, (evt) => { ajax(`http://authorize.com/${evt.target.id}`, ‘GET’, res => { ajax(`http://someapi.com/${res}`, ‘GET’, data => { setTimeout(() => { console.log(`finally some data: ${data}`) }, 500) }) }) });
Inversion of control / Инверсия контроля
Promise const promise = new Promise((resolve, reject) => { ajax(‘http://sample.com’, ‘GET’, done => resolve(done), err => reject(err)) }) promise .then(res => console.log(res)) .catch(err => console.log(‘Error occurred!’)) .finally(() => console.log(‘Hello from resolved/rejected promise!!’))
Promise features 1. No inversion of control, you get the future value 2. Immutable after resolve/reject 3. Completes only once (resolve/reject) 4. Chainable, always returns a Promise instance 5. Lighter syntax 6. Utilizes ES6 Jobs (acts like async microtask, not task) 7. Promise.all, Promise.race and more 8. Cannot be cancelled
Promise Chaining function createRequest(url) { return new Promise((resolve, reject) => { ajax(url, resolve, reject); // assume ajax is some http library }) } const promise = createRequest(‘http://auth.com’); promise.then(createRequest).then(createRequest).catch(console.log)
Handy to use Promise.all // resolves when all promises are resolved Promise.race // resolves when one of promises is resolved fetch // A modern replacement for XMLHttpRequest
async functions async function authorizeUser(user, pass) { const authUrl = await createRequest(`http://auth.com/${user}/${pass}`); const userData = await createRequest(authUrl); return userData; } authorizeUser(‘Jon Doe’, ‘very_secure_password’) .then(console.log).catch(console.log);
Good resources 1. https://www.youtube.com/watch?v=8aGhZQkoFbQ nice video about call stack and event loop 1. https://medium.com/front-end-hacking/callbacks-promises-and-async-await- ad4756e01d90 callback, Promise, async/await concepts 1. https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ tasks vs microtasks in event loop
Homework Create a function logNumbers() which accepts one argument of type ‘number’. After one second log into console this number + 10. After two seconds log into console previous step result * 3. After three seconds log into console previous step result - 20. Provide callback, Promise and async/await based solution.
Homework ** (only if you get bored with first one) fetch() is cool for HTTP requests. It’s Promise-based and has lots of options. But as Promise resolves/rejects only once and stays immutable, we cannot use it for reporting file upload progress purposes (PUT). Create a function which would provide a possible solution for this. Hint: this function will not use fetch()

Call stack, event loop and async programming

  • 1.
    Модель совпадения ицикл событий. Асинхронное выполнение, функции как колбэки, Promise Masters Academy, 2018
  • 5.
    1. Стэк (stack)контекстов выполнения функций программы 2. Куча (heap) - неструктурированная область памяти, для хранения объектов 3. Очередь событий (queue) - список событий, подлежащих обработке вследствие выполнения асинхронных операций
  • 6.
  • 7.
    function foo(x) { return5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15); “First in - last out” principle
  • 8.
    function foo(x) { return5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
  • 9.
    function foo(x) { return5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
  • 10.
    function foo(x) { return5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
  • 11.
    function foo(x) { return5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
  • 12.
    function foo(x) { return5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
  • 13.
    function foo(x) { return5 * x; } function bar(y) { return foo(y) - 3; } function baz(z) { return bar(z) + 7; } baz(15);
  • 14.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 15.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 16.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 17.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 18.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 19.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 20.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 21.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 22.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 23.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 24.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 25.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 26.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 27.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 28.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15);
  • 29.
    setTimeout(function() { console.log(‘timeout 500complete!’); }, 500); function foo(x) { return 5 * x; } setTimeout(function() { console.log(‘timeout 0 complete!’); }, 0); function baz(z) { console.log(foo(z) + 7) } baz(15); Output: // 82 // timeout 0 complete // timeout 500 complete
  • 30.
    Callbacks setTimeout(() => { console.log(‘HelloWorld!’) }, 1000); ajax(‘http://someurl.com’, ‘GET’, data => console.log(data)) // ajax in some http lib element.addEventListener(‘click’, evt => console.log(‘element clicked!!!’))
  • 31.
    Callback Hell button.addEventListener(‘click’, (evt)=> { ajax(`http://authorize.com/${evt.target.id}`, ‘GET’, res => { ajax(`http://someapi.com/${res}`, ‘GET’, data => { setTimeout(() => { console.log(`finally some data: ${data}`) }, 500) }) }) });
  • 33.
    Inversion of control/ Инверсия контроля
  • 34.
    Promise const promise =new Promise((resolve, reject) => { ajax(‘http://sample.com’, ‘GET’, done => resolve(done), err => reject(err)) }) promise .then(res => console.log(res)) .catch(err => console.log(‘Error occurred!’)) .finally(() => console.log(‘Hello from resolved/rejected promise!!’))
  • 35.
    Promise features 1. Noinversion of control, you get the future value 2. Immutable after resolve/reject 3. Completes only once (resolve/reject) 4. Chainable, always returns a Promise instance 5. Lighter syntax 6. Utilizes ES6 Jobs (acts like async microtask, not task) 7. Promise.all, Promise.race and more 8. Cannot be cancelled
  • 36.
    Promise Chaining function createRequest(url){ return new Promise((resolve, reject) => { ajax(url, resolve, reject); // assume ajax is some http library }) } const promise = createRequest(‘http://auth.com’); promise.then(createRequest).then(createRequest).catch(console.log)
  • 37.
    Handy to use Promise.all// resolves when all promises are resolved Promise.race // resolves when one of promises is resolved fetch // A modern replacement for XMLHttpRequest
  • 38.
    async functions async functionauthorizeUser(user, pass) { const authUrl = await createRequest(`http://auth.com/${user}/${pass}`); const userData = await createRequest(authUrl); return userData; } authorizeUser(‘Jon Doe’, ‘very_secure_password’) .then(console.log).catch(console.log);
  • 39.
    Good resources 1. https://www.youtube.com/watch?v=8aGhZQkoFbQnice video about call stack and event loop 1. https://medium.com/front-end-hacking/callbacks-promises-and-async-await- ad4756e01d90 callback, Promise, async/await concepts 1. https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ tasks vs microtasks in event loop
  • 40.
    Homework Create a functionlogNumbers() which accepts one argument of type ‘number’. After one second log into console this number + 10. After two seconds log into console previous step result * 3. After three seconds log into console previous step result - 20. Provide callback, Promise and async/await based solution.
  • 41.
    Homework ** (onlyif you get bored with first one) fetch() is cool for HTTP requests. It’s Promise-based and has lots of options. But as Promise resolves/rejects only once and stays immutable, we cannot use it for reporting file upload progress purposes (PUT). Create a function which would provide a possible solution for this. Hint: this function will not use fetch()