1. Ассинхронность.
JavaScript - однопоточен. Стоит в одной очереди с операциями отрисовки контента, обновления стилей и обработки пользовательских действий. Выполнение одной из этих операций тормозит всю очередь.
2. Сallback hell.
runAnimation(0);
setTimeout(function() {
runAnimation(1);
setTimeout(function() {
runAnimation(2);
}, 1000);
}, 1000);
1. Коллбэки являются функциями, обещания являются объектами
Коллбэки — это просто функции, которые выполняются в ответ на какое-либо событие. Любая функция может стать коллбэком, и любой коллбэк является функцией.
Обещания являются объектами, которые хранят информацию, произошли ли определенные события или нет, а если произошли — то и их результат.
2. Коллбэки передаются в качестве аргументов, обещания возвращаются
Коллбэки определяются независимо от вызывающей функции и передаются в качестве аргументов. Вызывающая функция сохраняет коллбэк и вызывает его, когда происходит определенное событие.
Обещания создаются внутри асинхронных функций и возвращаются. Когда происходит событие, асинхронная функция обновляет обещание, чтобы уведомить об этом внешний мир.
3. Коллбэки обрабатывают успешное или неуспешное завершение, обещания ничего не обрабатывают
Коллбэки, как правило, вызываются с информацией о том, успешно или неуспешно завершилась операция, и должны быть в состоянии обработать оба варианта.
Обещания ничего не обрабатывают по умолчанию, обработчики добавляются позже.
4. Коллбэки могут обрабатывать несколько событий, обещания связаны только с одним событием
Коллбэки можно вызывать несколько раз в функциях, в которые они переданы.
Обещания могут представлять только одно событие — они обратывают либо успешное его завершение, либо неуспешное только один раз.
Обещание может быть:
1. new Promise(fn)
let promise = new Promise(function(resolve, reject) {
// do a thing, possibly async, then…
if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
let promise = new Promise(function(resolve, reject) {
try {
// your code
}
catch (e) {
reject(e)
}
});
2. promise.then(onResolve,onReject) всегда возвращает обещание
// Только обработчик успеха
promise.then(function(details) {
// handle success
});
// Только обработчик отказа
promise.then(null, function(error) {
// handle failure
});
// Обработчики успеха и отказа
promise.then(
function(details) { /* handle success */ },
function(error) { /* handle failure */ }
);
delay(1000)
.then(function() {
return 5;
})
.then(function(value) {
console.log(value); // 5
});
3. promise.catch(onReject)
4. Promise.all([promise1, promise2, …])
Что она делает? Она возвращает обещание, которое успешно, если все аргументы успешны, и отклонен, когда любой из его аргументов отклонен. В случае успеха результирующее обещание содержит массив результатов каждого обещания, а в случае неудачи — ошибку первого неуспешного обещания.
Promise.all([
parallelAnimation1(),
parallelAnimation2()
]).then(function() {
finalAnimation();
});
promise.catch(handler) — это эквивалент promise.then(null, handler).
Text
// Асинхронная операция
function cookBurger (type) { ... }
// Обычная операция
function makeMilkshake (type) { ... }
// Функция оформления заказа, возвращает промис
function order (type) {
return new Promise(function(resolve, reject) {
var burger = cookBurger(type)
burger.ready = function (err, burger) {
if (err) {
return reject(Error('Error while cooking'))
}
return resolve(burger)
}
})
}
order('JakeBurger')
.then( burger => {
const milkshake = makeMilkshake('vanila')
return { burger: burger, shake: milkshake }
})
.then( foodItems => {
console.log('BURGER PARTY !', foodItems)
})
.catch( err => {
console.log(err)
})
Брелок молчит? —
заказ в процессе
Брелок загорелся красным и гудит? — заказ приготовлен.
«приготовлен» —
не значит «готов»
1) Вызывается `order` (делаете заказ).
2) Она возвращает `promise` (выдает поднос и брелок как обещание выполнить заказ).
3) Возвращённое значение (бургер) должен появиться на подносе, когда будет исполнен промис (данное вам обещание) и сработал колбэк.
При заказе коктейля кассир вручает вам другой поднос и еще один брелок. Так как напитки готовятся быстро, кассир сам выдает заказ, и не нужно ждать, когда загудит брелок (он уже гудит!).
1. Заказ исполнен
(resolve)
2. Заказ отклонен
(reject)
Метод .then() принимает вторым аргументом функцию. Эта функция является обработчиком для reject.
Но для простоты будем использовать для обработки ошибок только .catch().
Чтобы соединить промисы в цепочку, достаточно добавить еще один then(), он всегда возвращает промис.
Каждый .then() возвращает поднос и брелок, а текущее возвращаемое значение передается аргументом в коллбэк.
Теперь, когда у вас есть бургер и коктейль, вы готовы к БУРГЕРНОЙ ВЕЧЕРИНКЕ 🎉!
Promise.all() создает промис, принимающий массив промисов (items). Он исполняется, когда исполнены все элементы массива, каждый из которых тоже промис.
Promise.race() похож на Promise.all(), но исполнится или будет отклонен, как только будет исполнен или отклонен один из элементов массива промисов.
Promise.resolve(value) возвращает обещание, которое успешно завершено с переданным значением
Promise.reject(value) возвращает неуспешное обещание с переданным значением.
Promise – это не больно (видео)