Upload
jsib
View
95
Download
0
Embed Size (px)
Citation preview
pragmadash Денис РечкуновВедущий JavaScript-разработчик
Многообещающий JavaScript – Promises
За что я люблю JavaScript?• Очень удобно писать асинхронный код...
• JavaScript-код всегда исполняется в одном потоке
• Все "блокирующие" операции выполняются асинхронно
(в node.js это libuv)
• Благодаря Event Loop, не нужна синхронизация между потоками
(блокировки, каналы, вот это всё)
3
А зачем нам вообще асинхронный код?• Для параллельной обработки большого набора данных
• Чтобы процесс не простаивал, пока исполняется длительная операция
• К сожалению, для первого JavaScript совсем не годится
• Зато всё круто со вторым...
4
Callback HellcallACat(function () {
callADog(function () {
callAHorse(function () {
callSanta(function () {
console.log('Where am I?');
});
});
});
});
01.
02.
03.
04.
05.
06.
07.
08.
09.
7
Event Emitterphone
.on('cat', function(){ phone.callADog(); })
.on('dog', function(){ phone.callAHorse(); })
.on('horse', function(){ phone.callSanta(); })
.on('santa', function(){ console.log('Santa?'); });
phone.callACat();
01.
02.
03.
04.
05.
06.
8
Promisesphone.callACat()
.then(phone.callADog)
.then(phone.callAHorse)
.then(phone.callSanta)
.then(function(){ console.log('Santa?'); });
01.
02.
03.
04.
05.
9
Откуда они взялись?• "Promise" 1976 год – Daniel P. Friedman и David Wise
"Функция, возвращающая будущее значение"
• "Future" 1977 год – Henry Baker и Carl Hewitt
"Представление будущего значения"
Статья Википедии
11
Реализации• C++11 (std::future and std::promise)
• C# (System.Concurrent.Task, async/await)
• Java (java.util.concurrent.Future)
• Python (concurrent.futures)
• JavaScript (ECMAScript 6/2015)
12
Откуда они взялись в JavaScript?• Февраль 2010 Kris Kowal (Разработчик Q) предложил Promises/A
• 12 июня 2012 Brian Cavalier, Domenic Denicola и компания
предложили Promises/A+
• Спецификация Promises/A+, стала частью ECMAScript 6/2015
13
Важные факты• jQuery Promise не соответствует спецификации
• Каждый Promise начинает исполнение на след. итерации Event Loop
• Каждый последующий .then() или .catch() тоже на след. итерации
14
Терминология• Thenable – объект с методом .then (например jQuery Promise)
• Pending Promise – обещание ожидает значения
• Fulfilled Promise – выполненное обещание
• Rejected Promise – отвергнутое обещание
• Reason – описание, почему обещание отвергнуто
(обычно объект Error)
15
Вместо этого...callACat(function () {
callADog(function () {
callAHorse(function () {
callSanta(function () {
console.log('Where am I?');
});
});
});
});
01.
02.
03.
04.
05.
06.
07.
08.
09.
17
Вот это!phone.callACat()
.then(phone.callADog)
.then(phone.callAHorse)
.then(phone.callSanta)
.then(function(){ console.log('Santa?'); });
01.
02.
03.
04.
05.
18
Callback -> Promisenew Promise(function (fulfill, reject) {
phone.callACat(function (error, result) {
if (error) {
reject(error);
return;
}
fulfill(result);
});
});
01.
02.
03.
04.
05.
06.
07.
08.
09.
20
Thenable, Value -> PromisePromise.resolve(jQueryPromise);
Promise.resolve(number);
Promise.resolve(string);
Promise.reject(new Error('Cat not found'));
01.
02.
03.
04.05.
21
Chainingphone.callACat()
.then(function (catResult) {
console.log(catResult);
return phone.callADog(); // Promise
})
.then(function (dogResult) {
console.log(dogResult);
return 'Hello, Dog!'; // Value
})
.then(function (msg) { console.log(msg); }); // Hello, Dog!
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
22
Обработка ошибокphone.callACat()
.then(function () {
throw new Error('No cat!');
})
.then(function () {
console.log('This is a cat!'); // skipped
})
.catch(function (reason) {
console.error(reason); // No cat!
}) ;
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
23
Обработка ошибокphone.callACat()
.then(function () {
throw new Error('No cat!');
})
.then(function () {
console.log('This is a cat!'); // skipped
}, function (reason) {
console.error(reason); // No cat!
} ); // for old browsers no .catch
01.
02.
03.
04.
05.
06.
07.
08.
09.
24
Rethrow Errorphone.callACat('Tom')
.then(function () {
throw new Error('No cat!')
})
.catch(function (reason) {
reason.message += 'Tom';
throw reason;
});
01.
02.
03.
04.
05.
06.
07.
08.
25
Promise.all()Promise.all([
phone.callACat(),
phone.callADog(),
phone.callAHorse()
])
.then(function (resultsList) {
console.log('Everybody are online!');
});
01.
02.
03.
04.
05.
06.
07.
08.
26
Promise.race()Promise.race([
phone.callACat(),
phone.callADog(),
phone.callAHorse()
])
.then(function (value) {
console.log('Who is speaking?');
});
01.
02.
03.
04.
05.
06.
07.
08.
27
Полезные ссылки• Спецификация Promises/A+
• Mozilla Developer Network – Promise
• Коротко и понятно о Promises
• Чистый полифил Promise для старых браузеров
29