Фронтендщик
前往频道在 Telegram
Все для frontend developer, шуточки, тесты, статьи Администрация/Реклама @vtopua
显示更多1 058
订阅者
无数据24 小时
-47 天
-1330 天
帖子存档
1 058
Исправить проблему нам поможет Promise.resolve:
function func(num) {
if (num > 0) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(num * num);
}, 3000);
});
} else {
return Promise.resolve(0);
// возвращаем промис, а
не число
}
}
📌 #instr || Фронтендщик
1 058
Однако, теперь получается, что функция возвращает или промис, или число. Из-за этого мы больше не можем применить метод then к результату функции, так как в случае возврата функцией числа мы получим ошибку:
func(0).then(function(res)
{ // ошибка, применяем
метод then к нулю
});
📌 #instr || Фронтендщик
1 058
Мы будем пользоваться нашей функцией следующим образом:
func(5).then(function(res) {
console.log(res); // выведет
25
});
Пусть теперь мы решили, что нашу асинхронную операцию мы будем совершать, только если передано число больше нуля. В противном случае результатом функции должен быть ноль:
function func(num) {
if (num > 0) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(num * num);
}, 3000);
});
} else {
return 0; // нулевой
результат
}
}
📌 #instr || Фронтендщик
1 058
Когда нам может понадобится уже выполненный промис?
Давайте посмотрим на примере. Пусть у нас есть некоторая функция, которая параметром принимает число, что-то с ним делает асинхронно и возвращает промис с результатом:
function func(num) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(num * num);
}, 3000);
});
}
📌 #instr || Фронтендщик
1 058
Создание сработавших промисов в JavaScript
Иногда вам может понадобится создать уже выполненный промис. Для этого существуют два метода: метод
Promise.resolve создает выполненный успешно промис, Promise.reject создает отклоненный промис. Параметром эти методы получают то, что станет результатом или ошибкой промиса соответственно.
📌 #instr || Фронтендщик
1 058
Поэтому возникшее исключение можно поймать обычным, уже изученным вами способом, например, черезcatch:
Promise.all(promises).then(function(res) {
console.log(res);
}).catch(function(err) {
console.log(err);
});
📌 #instr || Фронтендщик
1 058
А теперь с помощью Promise.race дождемся окончания загрузки первого из промисов:
Promise.race(promises).then(function(res) {
console.log(res); // выведет
1 - результат первого выполнившегося
промиса
});
Если хотя бы один из промисов в массиве будет отклонен, то промис с результатом сразу же перейдет в состояние rejected.
📌 #instr || Фронтендщик
1 058
Давайте с помощью Promise.all дождемся окончания загрузки всех промисов из нашего массива:
Promise.all(promises).then(function(res) {
console.log(res); // выведет
[1, 2, 3] - результаты
всех промисов
});
📌 #instr || Фронтендщик
1 058
Давайте посмотрим на практике. Пусть у нас есть массив промисов:
let promises = [
new Promise(resolve
=> setTimeout(() => resolve(1),
1000)),
new Promise(resolve
=> setTimeout(() => resolve(2),
2000)),
new Promise(resolve
=> setTimeout(() => resolve(3),
3000)),
];
📌 #instr || Фронтендщик
1 058
Оба метода своим результатом возвращают новый промис. Для метода Promise.all результатом этого промиса будет массив результатов всех переданных промисов (порядок результатов соответствует порядку промисов в массиве), а для Promise.race - результат первого сработавшего промиса.
📌 #instr || Фронтендщик
1 058
Работа с массивами промисов в JavaScript
Сейчас мы разберем два полезных метода, позволяющих работать с массивами промисов. Метод Promise.all позволяет выполнить код по окончанию всех промисов, переданных ему в виде массива, а метод Promise.race дожидается загрузки первого промиса из массива, отбрасывая остальные.
📌 #instr || Фронтендщик
1 058
Учтите, что catch нужен именно для диагностики ошибки: она решаема или нет. Если ошибка решаема, то catch должен передать ее решение следующему за собой then. А если не решаема (или данный catch просто не знает как ее решить), то мы должны или ничего не вернуть или бросить исключение:
promise.then(
function(result) {
return result + ‘1’;
}
).then(
function(result) {
return result + ‘2’;
}
).catch(
function(error) {
if (ошибкаРешаема) {
return ‘данные’;
// отправляем на следующий
then
} else {
// ничего не возвращаем
или бросаем
исключение
}
}
).then(
function(result) {
// тут решаем ошибку
}
);
📌 #instr || Фронтендщик
1 058
При этом исключение может возникнуть в самом промисе, либо выброшено через throw в любом звене цепочки:
promise.then(
function(result) {
return result + ‘1’;
}
).then(
function(result) {
if (всеХорошо) {
return result + ‘2’;
} else {
throw new Error(‘ошибка’);
// переходим к ближайшему
перехватчику
}
}
)
.then(
function(result) {
return result + ‘3’;
}
).catch(
function(error) {
// ближайший перехватчик
}
);
📌 #instr || Фронтендщик
1 058
Как правило, все ошибки цепочки перехватываются в одном месте: в конце цепочки размещается catch:
promise.then(
function(result) {
return result + ‘1’;
}
).then(
function(result) {
return result + ‘2’;
}
).catch(
function(error) {
// попадем сюда в
случае ошибки
}
);
📌 #instr || Фронтендщик
1 058
Функция-обработчик имеет два варианта действий: если она справилась с исключительной ситуацией, то может вернуть результат через return и выполнение продолжится дальше по цепочке. Если же она не справилась с ошибкой, то может или ничего не возвращать, или выбросить исключение через throw. В этом случае выполнение перейдет к следующему перехватчику ошибки (в then или catch - что встретится раньше).
📌 #instr || Фронтендщик
1 058
Вот пример второй ситуации:
promise.then(
function(result) {
return result + ‘1’;
}
).then(
function(result) {
return result + ‘2’;
}
).catch(
function(error) {
// выполнение сразу
перейдет сюда
}
).then(
function(result) {
console.log(result);
}
);
📌 #instr || Фронтендщик
1 058
В этом случае выполнение кода сразу перейдет к тому then, в котором есть функция-обработчик ошибки, либо в первому catch, смотря что встретится раньше.
Вот пример первой ситуации:
promise.then(
function(result) {
return result + ‘1’;
}
).then(
function(result) {
return result + ‘2’;
},
function(error) {
// выполнение сразу
перейдет сюда
}
).then(
function(result) {
console.log(result);
}
);
📌 #instr || Фронтендщик
1 058
Исключения в цепочках промисов в JavaScript
Пусть по каким-то причинам наш промис завершится с ошибкой:
let promise = new
Promise(function(resolve,
reject) {
setTimeout(function() {
reject(‘error’);
}, 3000);
});
📌 #instr || Фронтендщик
1 058
Исключения в цепочках промисов в JavaScript
Пусть по каким-то причинам наш промис завершится с ошибкой:
let promise = new
Promise(function(resolve,
reject) {
setTimeout(function() {
reject(‘error’);
}, 3000);
});
📌 #instr || Фронтендщик
1 058
Промисы внутри цепочки в JavaScript
Функции цепочки могут также возвращать промисы. В этом случае результат этого промиса попадет в следующий then:
promise.then(
function(result) {
return result + ‘1’;
}
).then(
function(result) {
return new Promise(function(resolve) {
resolve(result +
‘2’); // этот результат
попадет в следующий then
});
}
).then(
function(result) {
return result + ‘3’;
}
).then(
function(result) {
console.log(result);
// выведет
‘string123’
}
);
📌 #instr || Фронтендщик
