Skip to content

Promise

garevna edited this page Feb 19, 2019 · 17 revisions

🎓 Promise

Примеры

Промис - это объект-администратор асинхронного процесса

Создается с помощью конструктора Promise

Он ничего не знает о процессе, который администрирует, но знает порядок вызова исполнителей

Ему нужно просто указать исполнителей

Исполнители - это функции

Предположим, вам выслали бандероль

"Новая почта" - функция, которая выполняет доставку бандероли

Она может доставить нам бандероль, а может потерять ( испортить ) отправление

Мы ждем доставку бандероли

Но при этом жизнь не останавливается, и мы не сидим день и ночь на ступеньках отделения "Новой почты"

Мы создаем объект, имеющий состояние - промис 🤖

Состояние объекта-промиса при создании - ожидание ⏳

Этот объект и будет сидеть вместо нас на ступеньках "Новой почты"

Его состояние ⏳ может в любой момент измениться на ✅ или ⛔

Сообщаем ему, какой процесс отслеживать - передаем ему функцию-исполнителя процесса 📮

В этой функции описан процесс, что и откуда должна доставить "Новая почта"

У этой функции есть два формальных параметра ( предположим, в бланке заказа нужно указать номера телефонов, по которым звонить в случае чего )

Эти формальные параметры - часть протокола действий функции-исполнителя при завершении процесса доставки:

📦 куда звонить, если бандероль благополучно доставлена
💥 куда звонить, если бандероль потерялась или испорчена
var 🤖 = new Promise (
 
    function ( 📦, 💥 ) {
        ...
        if ( 👍 ) 📦()
        else 💥()
    }
)

Итак, формальные параметры есть, но их значения пока не определены

Формально процедура описана

Осталось "заключить договор" и заполнить все бланки

В этом месте и подключается наш объект-промис 🤖

Мы должны проинформировать его, 📦 куда звонить, если бандероль благополучно доставлена ( наш сосед дядя Вася 👨‍⚕️ зайдет получить ее ) 💥 куда звонить, если бандероль потерялась или испорчена ( наш адвокат 👨🏻‍🎓 займется этой проблемой )

Как сообщить 🤖, что делать?

а у него есть метод then, с которым мы и передадим "номера телефонов":

🤖.then ( 👨‍⚕️ ).then ( 👨🏻‍🎓 )

Когда наша посылка будет доставлена, состояние нашего объекта-промиса изменится на ✅ и сработает первый .then ( будет вызван 👨‍⚕️ )

Если же станет известно, что посылка была испорчена или утеряна, то состояние нашего объекта-промиса станет ⛔ и сработает второй .then ( будет вызван 👨🏻‍🎓 )

Таким образом, созданный нами 🤖 - это объект, в который мы "завернули" процесс доставки-получения бандероли, расписав исполнителей, чтобы больше не заморачиваться

var 🤖 = new Promice ( 📮 ( 📦, 💥 ) )
🤖.then ( 👨‍⚕️ ).then ( 👨🏻‍🎓 )

где 📦 и 💥 - формальные параметры, значения которых передаются промису 🤖 через .then

в случае, если состояние 🤖 станет ✅, 📦 получит фактическое значение 👨‍⚕️,

в случае, если состояние 🤖 станет ⛔, 💥 получит фактическое значение 👨🏻‍🎓


☕ Примеры

Итак, объект 🤖 создается с помощью конструктора Promise

Параметр, который передается конструктору - это функция, выполняющая некую асинхронную операцию

Эта функция, в свою очередь, получает на входе два параметра, оба - коллбэки, т.е. функции

☕ 1️⃣

var promise = new Promise ( 
    function ( resolve, reject ) { 
        ...
        if ( ... ) resolve 
        else reject 
    } 
)

☕ 2️⃣

Используем Battery API для получения инфо о зарядке аккумулятора

( метод getBattery() объекта navigator возвращает промис ):

navigator.getBattery().then ( result => {
    for ( var x in result ) 
        console.log ( `${x}: ${result[x]}` )
})

☕ 3️⃣

var promises = [
    new Promise ( resolve => setTimeout ( () => resolve ( "Hello" ), 1000 ) ),
    new Promise ( resolve => setTimeout ( () => resolve ( "Bye" ), 3000 ) ),
    new Promise ( resolve => setTimeout ( () => resolve ( "How are you?" ), 2000 ) )
]

Promise.all ( promises ).then ( response => document.body.innerHTML += `<p>${response}</p>` )
☕ 4️⃣ ☕ 5️⃣ ☕ 6️⃣

☕ 7️⃣

Для понимания полезности промисов в нашей асинхронной жизни рассмотрим простенький пример

console.log ( "hello" )
let promise = new Promise (
    ( resolve, reject ) => resolve ( "Promise successfully rejected" )
)

promise.then ( response => console.log ( response ) )
console.log ( "wait for promise" )

Обратите внимание, что функция, переданная конструктору Promise, отнюдь не асинхронная

Однако, завернув ее в промис, мы убрали ее из основного потока

Она будет выполнена тогда, когда Call Stack освободится, т.е. все текущие операции в основном потоке завершатся

Это позволяет избежать блокирующих операций

Если какой-то фрагмент кода содежит слишком "тяжеловесные" вычисления или операции, которые могут длиться достаточно долго, чтобы заблокировать основной поток - заверните такой код в промис, и он "уйдет" в Event Loop

Почти аналогичного результата можно достичь с помощью таймера с нулевой задержкой:

console.log ( "start" )

setTimeout (
    () => console.log ( "Timeout is over" ),
    0
)

console.log ( "Application finished" )

Однако результат с таймером все-таки отличается от результата с промисом

В первом случае ( с промисом ) приложение не завершает работу, пока промис не вернет результат

В случае с таймером приложение завершит работу к тому моменту, когда колбэк таймера сработает

console.log ( "Start" )

setTimeout ( () => console.log ( "Timeout is over" ), 0 )

let promise = new Promise (
    ( resolve, reject ) => resolve ( "Promise successfully rejected" )
)

promise.then ( response => console.log ( response ) )

console.log ( "Finish" )

Запустите этот код в консоли и обратие внимание, что таймер сработает после промиса, хотя промис в коде следует за таймером

Start
Finish
Promise successfully rejected
undefined   // выполнение кода основного потока завершено
Timeout is over

© Irina H.Fylyppova 2018
Использование данных материалов или любой их части коммерческими школами ( курсами ) является нарушением авторских прав


Новая версия


1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19

Занятие 1

⤵️

Занятие 2

⤴️ ⤵️

Занятие 3

⤴️ ⤵️

Занятие 4

⤴️ ⤵️

Занятие 5

⤴️ ⤵️

Занятие 6

⤴️ ⤵️

Занятие 7

⤴️ ⤵️

Занятие 8

⤴️ ⤵️

Занятие 9

⤴️ ⤵️

Занятие 10

⤴️ ⤵️

Занятие 11

⤴️ ⤵️

Занятие 12

⤴️ ⤵️

Занятие 13

⤴️ ⤵️

Занятие 14

⤴️ ⤵️

Занятие 15

⤴️ ⤵️

Занятие 16

⤴️ ⤵️

Занятие 17

⤴️ ⤵️

Занятие 18

⤴️ ⤵️

Занятие 19

⤴️ ⤵️

⤴️

ico20 Дополнительно
dir-20 Справочная инфо

Clone this wiki locally