Меню

Promises in JS

05.07.2018 - java script, ЯП

Promise

Что такое промис?
Промис это объект, который содержит возможный результат асинхронной операции.
Т.е. когда асинхронная операция завершена, он выдаст результат, значение или ошибку. По простому, промис обещает вам, что отдаст результат асинхронной операции. У этого объекта 3 состояния. В самом начале, когда мы создаем промис объект, он находится в состоянии pending. В этом состоянии он выполняет какую то асинхронную операцию. Когда результат готов, промис становится либо в состояние fulfilled или (resolve), что означает что операция была выполнена успешно и у нас есть значение.

В ином случае, если что то пошло не так во время выполнения асинхронной операции — промис примет состояние rejected. В этом случае мы считаем что у нас ошибка.

promise

Теперь давайте посмотрим на это в действии.

Создадим файл promise.js И создадим в нем новый промис с помощью конструктора Promise, который в качестве аргумента принимает функцию с двумя параметрами — resolve и reject. Внутри этой функции выполняется какая либо асинхронная операция. В итоге, асинхронная операция завершается. У нас должно быть либо значение, либо ошибка. Если это значение, то мы должны вернуть его потербителям этого промиса. Потому что этот промис объект, обещал нам отдать результат нашей асинхронной операции. Способ сделать это — использовать resolve или reject. По просту говоря, это функции. Например, мы можем вызвать resolve и передать результат ей в качестве аргумента. Мы используем эту функцию, чтобы передать результат тому, что вызвал этот промис.

В ином случае, если что то пошло не так, мы должны передать ошибку пользователю этого промиса. В этом случае, вместо resolve, мы вызываем reject. В качестве аргумента мы можем передать сообщение с ошибкой.

Best Practice передать в качестве аргумента объект ошибки вместо обычной строки.

const p = new Promise((resolve, reject) => {
    reject(new Error('message'));
})

Теперь давайте представим, что асинхронная операция завершилась успешно, и произвела единицу как результат. В реальном приложении получили бы, например, объект user из базы данных. Теперь нам нужно использовать результат где то в коде.

const p = new Promise((resolve, reject) => {
    resolve(1);
})

В нашем объекте p, который является экземпляром промиса, есть два метода catch — для отловки всякого рода ошибок и then — для получения результата нашей асинхронной операции. Итак здесь мы вызовем then, которая в качестве аргумента принимает функцию. В эту функцию передается переменная, которая и является аргументом, который был передан в resolve внутри промиса. Пока, чисто для теста выведем результат в консоли

p.then(result => {
    console.log(`Result: ${result}`);
})

У нас пока не было асинхронной операции в промисе. Давайте добавим туда.

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(1);
    }, 2000);
});

p.then(result => console.log('Result: ', result)).catch(err => console.log(err));

Как и говорили, иногда во время выполнения промиса, а точнее асинхронной операции, что-то может пойти не так. Тогда вместо resolve, мы будем использовать reject. Для отлова ошибок у нас в экземпляре промиса есть метод catch. Каждое сообщение которое мы передаем в объект Error в качестве аргумента, сохраняется в переменной message.

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        // resolve(1);
        reject(new Error('Some error'))
    }, 2000);
});

p.then(result => console.log('Result: ', result)).catch(e => console.log(e));

При этом раскладе мы получим ошибку в нашей консоли, так как мы реджекнули промис.

Также ошибку принимает функция, которую можно передать вторым параметром в then.

p.then(result => console.log('Result: ', result),
       error => console.error('Обшибка ', error))
 .catch(e => console.log(e));
Метки: , ,

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *