Promise Flashcards
what is promise chaining
Promise chaining is a syntax that allows you to chain together multiple asynchronous tasks in a specific order. This is great for complex code where one asynchronous task needs to be performed after the completion of a different asynchronous task
Идея состоит в том, что результат первого промиса передаётся по цепочке обработчиков .then.
- Начальный промис успешно выполняется через 1 секунду (*),
- Затем вызывается обработчик в .then (**).
- Возвращаемое им значение передаётся дальше в следующий обработчик .then (***)
результат выполнения кода?
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
});
promise.then(function(result) {
alert(result);
return result * 2;
});
promise.then(function(result) {
alert(result);
return result * 2;
});
1
Поток выполнения такой:
Начальный промис успешно выполняется через 1 секунду (*)
what is promise in js?
Можно ли “перевыполнить” промис?
Что выведет код ниже?
let promise = new Promise(function(resolve, reject) { resolve(1);
setTimeout(() => resolve(2), 1000);
});
promise.then(alert);
решение
Вывод будет: 1.
Второй вызов resolve будет проигнорирован, поскольку учитывается только первый вызов reject/resolve. Все последующие вызовы – игнорируются.
Встроенная функция setTimeout использует колбэк-функции. Создайте альтернативу, использующую промисы.
function delay(ms) { // ваш код }
delay(3000).then(() => alert(‘выполнилось через 3 секунды’));
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
delay(3000).then(() => alert(‘выполнилось через 3 секунды’));
Заметьте, что resolve вызывается без аргументов. Мы не возвращаем из delay ничего, просто гарантируем задержку.
для чего используется catch
Цепочки промисов отлично подходят для перехвата ошибок. Если промис завершается с ошибкой, то управление переходит в ближайший обработчик ошибок. На практике это очень удобно.
Например, для fetch указана неправильная ссылка (сайт не существует), и .catch перехватывает ошибку:
fetch(‘https://no-such-server.blabla’) // ошибка
.then(response => response.json())
.catch(err => alert(err)) // TypeError: failed to fetch (текст может отличаться)
Как видно, .catch не обязательно должен быть сразу после ошибки, он может быть далее, после одного или даже нескольких .then
Или, может быть, с сервером всё в порядке, но в ответе мы получим некорректный JSON. Самый лёгкий путь перехватить все ошибки – это добавить .catch в конец цепочки
Что происходит, когда обычная ошибка не перехвачена try..catch? И в случае необработанной ошибки промиса.
Скрипт умирает с сообщением в консоли.
JavaScript-движок отслеживает такие ситуации и генерирует в этом случае глобальную ошибку. Вы можете увидеть её в консоли.
Promise Methods. What is Promise.all?
Promise.all
Допустим, нам нужно запустить множество промисов параллельно и дождаться, пока все они выполнятся.
Например, параллельно загрузить несколько файлов и обработать результат, когда он готов.
Для этого как раз и пригодится Promise.all.
let promise = Promise.all(iterable); Метод Promise.all принимает массив промисов (может принимать любой перебираемый объект, но обычно используется массив) и возвращает новый промис.
Новый промис завершится, когда завершится весь переданный список промисов, и его результатом будет массив их результатов.
Promise Methods Если любой из промисов в Promise.All завершится с ошибкой что будет дальше?
Если один промис завершается с ошибкой, то весь Promise.all завершается с ней, полностью забывая про остальные промисы в списке. Их результаты игнорируются.
Например, если сделано несколько вызовов fetch, как в примере выше, и один не прошёл, то остальные будут всё ещё выполняться, но Promise.all за ними уже не смотрит. Скорее всего, они так или иначе завершатся, но их результаты будут проигнорированы.
*Promise Methods What is Promise.allSettled
Cинтаксис:
let promise = Promise.allSettled(iterable); Promise.all завершается с ошибкой, если она возникает в любом из переданных промисов. Это подходит для ситуаций «всё или ничего», когда нам нужны все результаты для продолжения:
Метод Promise.allSettled всегда ждёт завершения всех промисов. В массиве результатов будет
{status:”fulfilled”, value:результат} для успешных завершений,
{status:”rejected”, reason:ошибка} для ошибок.
Например, мы хотели бы загрузить информацию о множестве пользователей. Даже если в каком-то запросе ошибка, нас всё равно интересуют остальные.
Promise methods Что такое Полифил?
Если браузер не поддерживает Promise.allSettled, для него легко сделать полифил:
if(!Promise.allSettled) { Promise.allSettled = function(promises) { return Promise.all(promises.map(p => Promise.resolve(p).then(value => ({ status: 'fulfilled', value: value }), error => ({ status: 'rejected', reason: error })))); }; }
Promise Methods Promise.race
Метод очень похож на Promise.all, но ждёт только первый выполненный промис, из которого берёт результат (или ошибку).
Синтаксис:
let promise = Promise.race(iterable); Например, тут результат будет 1:
Promise.race([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error(“Ошибка!”)), 2000)),
new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).then(alert); // 1
Быстрее всех выполнился первый промис, он и дал результат. После этого остальные промисы игнорируются.
Promise Methods resolve/reject
Promise.resolve(value) создаёт успешно выполненный промис с результатом value.
Promise.reject(error) создаёт промис, завершённый с ошибкой error.
- что такое Промисификация ?
Эта функция-обёртка возвращает промис и передаёт вызов оригинальной f, отслеживая результат в своём колбэке:
Обработчики промисов .then/.catch/.finally всегда асинхронны?
да
что будет в результате выполнения, почему?
let promise = Promise.resolve();
promise.then(() => alert(“промис выполнен”));
alert(“код выполнен”);
сначала код выполнен, а потом промис выполнен.
Асинхронные задачи требуют правильного управления. Для этого стандарт предусматривает внутреннюю очередь PromiseJobs, более известную как «очередь микрозадач (microtask queue)» (термин V8).
Как сказано в спецификации:
Очередь определяется как первым-пришёл-первым-ушёл (FIFO): задачи, попавшие в очередь первыми, выполняются тоже первыми.
Выполнение задачи происходит только в том случае, если ничего больше не запущено.
Или, проще говоря, когда промис выполнен, его обработчики .then/catch/finally попадают в очередь. Они пока не выполняются. Движок JavaScript берёт задачу из очереди и выполняет её, когда он освободится от выполнения текущего кода.
Вот почему сообщение «код выполнен» в примере выше будет показано первым.
what is Async/await? Syntaxis? benefits? what returns by async?
Ключевое слово await заставит интерпретатор JavaScript ждать до тех пор, пока промис справа от await не выполнится. После чего оно вернёт его результат, и выполнение кода продолжится.
По сути, это просто «синтаксический сахар» для получения результата промиса, более наглядный, чем promise.then.
What is async/await?
async/await is a new way to write promise chains in a shorter way.
For example, instead of calling the then function with a callback like we had above, we rewrite it to:
try { const readFileData = await promiseReadFile('somefile.txt'); console.log(readFileData); const readDirData = await promiseReadDir('directory'); console.log(readDirData); const makeFileData = await promiseMakwDir('directory'); console.log(makeFileData); return makeFileData; } catch(err){ console.log(err); } })();
what is a result of
async function f() {
return 1;
}
f().then(alert);
1
how/where to use following code
let value = await promise;
only inside async function
how to handle error in async function?
async function f() { let response = await fetch('http://no-such-url'); }
// f() вернёт промис в состоянии rejected f().catch(alert); // TypeError: failed to fetch // (*)
Если забыть добавить .catch, то будет сгенерирована ошибка «Uncaught promise error» и информация об этом будет выведена в консоль.
Такие ошибки можно поймать глобальным обработчиком, о чём подробно написано в разделе Промисы: обработка ошибок.???
developpaper
var p = new Promise((resolve, reject) => {
reject(Error(‘The Fails!’))
})
p.catch(error => console.log(error.message))
p.catch(error => console.log(error.message))
What will the output of the above code be? Please choose the correct answer:
[] print a message once
[] Print the message twice
[ ]UnhandledPromiseRejectionWarning
[] program exit
Print the message twice
We use the constructor method to create a promise and immediately trigger the error through the reject callback.
then. Catch works similarly to dom Addeventlistener (event, callback) or event emitter On (event, callback), where multiple callbacks can be added. Each is called with the same parameters.
developpaper
var p = new Promise((resolve, reject) => {
return Promise.reject(Error(‘The Fails!’))
})
p.catch(error => console.log(error.message))
p.catch(error => console.log(error.message))
What will the output of the above code be? Please choose the correct answer:
[] print a message once
[] print message twice
[]UnhandledPromiseRejectionWarning
[] program exit
[x]UnhandledPromiseRejectionWarning
When using promise constructor, you must call the resolve() or reject() callback. Promise constructor doesn’t use your return value, so it won’t actually receive any more from promise Other promises created by reject().
developpaper
var p = new Promise((resolve, reject) => {
reject(Error(‘The Fails!’))
})
.catch(error => console.log(error))
.then(error => console.log(error))
What will the output of the above code be? Please choose the correct answer:
[] Print errors and undefined
[] print twice error
[ ]UnhandledPromiseRejectionWarning
[ ]undefined
Print errors and undefined
When link Then and When you catch, it’s helpful to think of them as a series of steps. Each Then all receive the previous one Then returns the value as its parameter. However, if your “step” encounters an error, no follow-up action will be taken Then “steps” will be skipped until they are encountered catch。 If you want to overwrite the error, all you have to do is return a non error value. This can be done by any subsequent Then visit.
Tip: console Log() always returns undefined.
developpaper
var p = new Promise((resolve, reject) => {
reject(Error(‘The Fails!’))
})
.catch(error => console.log(error.message))
.catch(error => console.log(error.message))
What will the output of the above code be?
[] Print an error message
[] print error message twice
[ ] UnhandledPromiseRejectionWarning
[] program exit
Print an error message
When link When catching, each process only the previous Then or ` Error raised in catch step. In this case, the first one Catch returns console Log can only be passed in two Add after catch Then().