Базовые задачи на Promise в JavaScript

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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, необходимо изучить теорию и приступать к практике. Стоит практиковать задачи в различных вариациях: расширять задачи, изменять существующие примеры и отслеживать изменения.

На этом всё. И да прибудет с нами сила!

Источник: https://habr.com/ru/post/582914/


Интересные статьи

Интересные статьи

Не стоит недооценивать силу простоты. Пожалуй, сложно представить себе, что на чистом JavaScript реализовано что-то вроде системы push-уведомлений, работающей в реальном времени, или инст...
Привет! Меня зовут Анастасия, психолог и много консультирую IT-специалистов. И я вижу большое сходство в работе тимлида и психолога. В чём оно? Работа с людьми, безусловно. А если конкрет...
Math.random() — это один из API JavaScript. Это — функция, которая возвращает случайные числа. Диапазон возвращаемых чисел представлен значениями от 0 (включая 0, то есть, она может верну...
Если вы, до того, как заинтересовались JavaScript, писали на традиционных языках с сильной типизацией, то вы, возможно, знакомы с концепцией void. Это — тип, использование которого сообщает прогр...
В этой статье я расскажу об одной необычной формуле, которая позволяет взглянуть под новым углом на аффинные преобразования, а особенно на обратные задачи, которые возникают в связи с этими преоб...