Promise - специальный объект, который хранит своё состояние и используется для обработки результатов асинхронных операций.
Что будет в статье:
Основные задачи на Promsie, которые часто спрашивают на собеседованиях
Код задач с подробными комментариями
Чего в статье НЕ будет:
Теории про Promsie и Event Loop
Задач на Event Loop, показывающих приоритетность выполнения Promise, setTimeout и т.д.
Статья предназначена для тех, кто уже изучил теорию по Promise и хочет попрактиковаться в решении тестовых задач.
Основные методы Promise
Приведу список методов, которые будут использоваться а задачах:
"Promise.resolve(value)"- создаёт успешно выполнившийся Promise с результатом value"Promise.reject(value)"- создаёт выполнившийся Promise с ошибкой".then"- обработчик событий Promise"onFulfilled"и"onRejected"".catch"- обработчик события Promise"onRejected"".finally"- дает возможность запустить один раз определенный участок кода, который должен выполниться вне зависимости от того, с каким результатом выполнился Promise
Задачи на .then
1. Случаи, когда .then возвращает или не возвращает значение
Promise.resolve("1") // Promise.resolve вернул "1" .then(data => { console.log(data); // => "1" }) // .then ничего не вернул .then(data => { console.log(data); // => "undefined" return "2"; }) // .then вернул "2" .then(data => { console.log(data); // => "2" })
2. Второй аргумент .then
Первая задача
Promise.reject(1) // skip // обработать reject можно только в .catch .then(data => { console.log(data); }) // второй аргумент .then вместо .catch .then(null, data => console.log(data)) // => 1 // после обработки ошибки попадаем в .then // => "ok" .then(() => console.log('ok'));
Вторая задача
Promise.reject() // используем колбэки для .then и для .catch .then( data => console.log('ok'), // => skip data => console.log('error') // => "error" )
3. null в .then
Promise.resolve("1") // skip .then(null) // придут данные из Promise.resolve .then(data => console.log(data)) // => "1"
Задачи на .catch
1. Ошибка из Promise.reject
Promise.reject("Api Error") // skip из-за Promise.reject .then(data => console.log('ok')) // обработка ошибки .catch(error => { console.log(error); // => "Api Error" return "1"; }) // catch вернул "1" .then(data => { console.log(data); // => "1" })
2. Ошибка из Promise.reject в .catch
Promise.reject() // обработка Promise.reject .catch(() => { console.log('error1'); // => "error1" return Promise.reject(); // аналогично // return reject(); }) // обработка Promise.reject из предыдущего .catch .catch(() => { console.log('error2'); // => "error2" })
3. Ошибка throw new Error
Promise.resolve() .then(data => { // возникновение ошибки throw new Error('Api Error'); // не имеет значения, что вернули return 1; }) // skip, потому что предыдущий .then бросил ошибку .then(data => console.log('ok')) // обработка ошибки .catch(error => { console.log(error.message); // => "Api Error" return "2"; }) // .catch вернул "2" .then(data => { console.log(data); // => "2" })
4. Необработанная ошибка в Promise
Необработанная ошибка в Promise не влияет на работу программы, т.к. Promise не выпускает ошибку за свои пределы.
Promise.resolve() .then(() => { throw new Error('Api Error'); }) // код будет работать setTimeout(() => { console.log('setTimeout'); // => "setTimeout" }, 1000);
5. null в .catch
Promise.reject("Api Error") // skip: ошибку не обработали .catch(null) // skip из-за необработанной ошибки .then(data => console.log('ok')) // обработка ошибки .catch(error => console.log(error)) // => "Api Error" // .then выполнится .then(data => console.log('ok')) // => "ok"
Задачи на .finally
Первая задача
Promise.resolve() .then(() => { return "1"; }) // .then вернул "1", но .finally пропустит его мимо себя .finally(data => { console.log(data); // => "undefined" return "2"; }) // из .finally вернули "2", но результат берется из предыдущего .then или .catch .then(data => console.log(data)) // => "1"
Вторая задача
Promise.reject() // .finally выполняется в любом случае: даже при возникновении ошибки .finally(data => { console.log('finally'); // => "finally" })
Задачи на несколько Promise
Если несколько Promise, то
".then"будет выполняться последовательно для каждого:
Promise.resolve() .then(() => console.log(1)) // "Первый" .then(() => console.log(2)) // "Третий" Promise.resolve() .then(() => console.log(11)) // "Второй" .then(() => console.log(12)) // "Четвертый"
При
".catch"аналогично:
Promise.resolve() .then(() => console.log(1)) // "Первый" .then(() => { console.log(2); throw new Error(); }) // "Третий" .catch(() => console.log(3)) // "Пятый" .then(() => console.log(4)) // "Седьмой" Promise.resolve() .then(() => console.log(11)) // "Второй" .then(() => { console.log(12); throw new Error(); }) // "Четвертый" .catch(() => console.log(13)) // "Шестой" .then(() => console.log(14)) // "Восьмой"
Задача на бесконечные микротаски
В качестве бонуса покажу, как повесить браузер микротасками, которыми являются Promise:
const foo = () => { Promise.resolve().then(() => foo()) } foo();
Заключение
В статье я собрал базовые задачи с собеседований. Чтобы понять Promise, необходимо изучить теорию и приступать к практике. Стоит практиковать задачи в различных вариациях: расширять задачи, изменять существующие примеры и отслеживать изменения.
На этом всё. И да прибудет с нами сила!
