Полный цикл в digital

Получение результата в Promise

Допустим, папа обещает дать 100$, если вы сдадите завтрашний экзамен на хорошо или отлично.

В данный момент вы находитесь в состоянии ожидания, т.к. не знаете какую отметку вы получите, а следовательно, не знаете получите ли вы бонус в размере 100$.

Но как только вы получите отметку по экзамену, обещание завершится. Далее в зависимости от того успешно оно завершилось или нет будет зависеть получите ли вы 100$ или нет.

На JavaScript этот пример с помощью promise реализуется следующим образом:

// создадим новый промис
const promise = new Promise((resolve, reject) => {
    // оценку, которые мы получим определим случайным образом спустя некоторое время (например, 5 секунд)
    setTimeout(() => {
        // сгенерируем оценку от 2 до 5
        const mark = Math.floor(Math.random() * 4) + 2;
        // если оценка больше 3, то...
        if (mark > 3) {
            // завершим промис успешно: для этого вызовем функцию resolve() и передадим ей в скобках полученную оценку (это нужно для того, чтобы мы затем её могли получить в методе then())
            resolve(mark);
        } else {
          // завершим промис с ошибкой
          reject(mark);
        }
    }, 5000);
});
promise
    // then выполнится в случае успеха
    .then(result => console.log(`Ура! Я сдал экзамен на ${result}! Папа, как и обещал дал мне 100$.`))
    // catch выполнится в случае ошибки
    .catch(result => console.log(`Увы, я получил оценку ${result}! Папа мне не дал 100$`));

Создание промиса

Начинается процесс написания промиса с его создания. Осуществляется это с помощью конструктора, new Promise():

const promise = new Promise((resolve, reject) => {
  // асинхронный код
});

Конструктор промиса принимает 2 аргумента, которые являются функциями. Первый аргумент обычно называют resolve, а второй – reject. Внутрь промиса помещают асинхронный код, можно конечно и синхронный, но тогда в этом не будет смысла.

Промис завершает своё выполнение, когда вызывается функция resolve() или reject().

Функцию resolve() вызывают обычно в том месте кода, в котором асинхронная операция должна завершиться успешно. А функцию reject() – там, где она должна завершиться с ошибкой.

Состояния, в которых может находиться промис

Промис начинается с состояния ожидания state: "pending". Оно говорит о том, что он ещё не выполнен, результат undefined.

Промис завершается после вызова resolve() или reject(). При этом его состояние переходит соответственно в выполнено state: "fulfilled" или отклонено state: "rejected".

Внутрь функций resolve() или reject() можно поместить аргумент, который затем будет доступен соответственно в then() или catch():

const passexam = true;
// промис
const result = new Promise((resolve, reject) => {
  setTimeout(() => {
    passexam ? resolve('Папа подарил 100$.') : reject('Папа не подарил 100$.');
  }, 5000);
});
result
  .then(value => {
    console.log(result);
    console.log(value);
  })
  .catch(value => {
    console.log(result);
    console.error(value);
  });

Методы промисов

У каждого промиса есть определённый набор методов, которые мы можем использовать:

  1. then выполняется, когда промис завершился успешно (после вызова функции resolve())
  2. catch вызывается, если промис завершается ошибкой (после вызова reject())
  3. finally выполняется в любом случае после завершения промиса, вне зависимости от конечного состояния

Пример с использованием всех трёх методов:

<div><button id="run">Новая попытка</button></div>
<div id="result"></div>
<script>
  let isProcess = false;
  elResult = document.querySelector('#result');
  document.querySelector('#run').onclick = () => {
    if (isProcess) {
      elResult.textContent = 'Подождите! Задача ещё выполняется!';
      return;
    }
    isProcess = true;
    elResult.textContent = 'Задача в процессе...';
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        const mark = Math.floor(Math.random() * 4) + 2;
        mark > 3 ? resolve(mark) : reject(mark);
      }, 5000);
    });
    promise
      .then(value => {
        elResult.textContent = `Ура! Вы сдали экзамен на ${value}! Папа, как и обещал дал вам 100$.`;
      })
      .catch(value => {
        elResult.textContent = `Увы, вы получили оценку ${value}! Папа не дал вам 100$`;
      })
      .finally(() => {
        isProcess = false;
      });
  }
</script>

При этом then() позволяет обработать не только успех, но и ошибку. Для этого необходимо передать функцию в качестве второго аргумента:

promise.then(
  // действия при успешном завершении промиса
  value => {  },
  // действия при завершении промиса с ошибкой
  error => {  }
);

Второй аргумент указывать не обязательно, в этом случае он будет реагировать только на успех:

promise.then(value => {
  // действия при успешном завершении промиса
});

Для того чтобы получить значение из промиса в методах then() и catch() как уже было отмечено выше необходимо его передать в функции resolve() и reject().

Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг