@justedoit

Как выбросить ошибку из промиса?

Здравствуйте.

Есть код
function increaseSalary() {
  return new Promise((resolve, reject) => {
    let minSalaryEmployee = api.getEmployees().then((employeeData) => {
      const minSalary = Math.min(...employeeData.map(({ salary }) => salary));
      minSalaryEmployee = employeeData.filter(({ salary }) => {
        return salary === minSalary;
      });
      const [id, oldSalary] = [
        minSalaryEmployee[0].id,
        minSalaryEmployee[0].salary,
      ];
      const newSalary = oldSalary + (oldSalary / 100) * 20;
      return { id: id, salary: newSalary };
    })
    minSalaryEmployee.then((data) => {
      let newSalary = api.setEmployeeSalary(data.id, data.salary);
      newSalary
        .then((newData) => {
          const { name, id, salary } = newData;
          const notifyEmployee = api.notifyEmployee(
            id,
            `Hello, ${name}! Congratulations, your new salary is ${salary}!`
          );
          resolve(notifyEmployee);
        }).catch((e) => api.notifyAdmin(e));
    })
  });
}


нужно выбросить ошибку когда в метод api.setEmployeeSalary() передается ошибка(new Error), и передать ошибку в api.notifyAdmin(error). Мой пример который не работает .catch((e) => api.notifyAdmin(e));

Подскажите пожалуйста.
  • Вопрос задан
  • 669 просмотров
Решения вопроса 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Ваша главная проблема в говнокоде, в котором Вы сами не в состоянии разобраться.

Для начала я отрефакторю вот этот кусок:
const minSalary = Math.min(...employeeData.map(({ salary }) => salary));
minSalaryEmployee = employeeData.filter(({ salary }) => {
    return salary === minSalary;
});
const [id, oldSalary] = [
    minSalaryEmployee[0].id,
    minSalaryEmployee[0].salary,
];
const newSalary = oldSalary + (oldSalary / 100) * 20;
return { id: id, salary: newSalary };
ибо тут твориться полная жесть...
Если привести в более читабельный вид:
const minSalary = Math.min(...employeeData.map(({salary}) => salary));
const minSalaryEmployee = employeeData.find(({salary}) => salary === minSalary);
const {id, salary: oldSalary} = minSalaryEmployee;
const newSalary = oldSalary + (oldSalary / 100) * 20;
return {id, salary: newSalary};
то сразу можно увидеть простор для оптимизации поиска минимума:
const [minSalaryEmployee] = employeeData.reduce(([minEmployee, minSalary], employee) => {
    const {salary} = employee;
    return (salary < minSalary
        ? [employee, salary]
        : [minEmployee, minSalary]
    );
}, [null, Infinity]);
А заодно и формулу
const newSalary = oldSalary + (oldSalary / 100) * 20;
применив алгебру за 5 класс можно упростить доconst newSalary = oldSalary * 1.2;

Следующим шагом стоит развернуть все промисы. Вообще вкладывать промисы в друг друга не очень хорошая идея. Наличие .then внутри колбэка другого .then или колбэка-раннера new Promise - воняет очень скверно.

Немного поколдовав, заодно исправив ошибки с колбэками .then без return, получаем более читабельный, а главное работающий код:
function increaseSalary() {
    return api.getEmployees()
        .then(employeeData => {
            const [minSalaryEmployee] = employeeData.reduce(([minEmployee, minSalary], employee) => {
                const {salary} = employee;
                return (salary < minSalary
                    ? [employee, salary]
                    : [minEmployee, minSalary]
                );
            }, [null, Infinity]);
            const {id, salary: oldSalary} = minSalaryEmployee;
            const newSalary = oldSalary * 1.2;
            return {id, salary: newSalary};
        })
        .then(({id, salary}) => api.setEmployeeSalary(id, salary))
        .then(({name, id, salary}) => api.notifyEmployee(id, `Hello, ${name}! Congratulations, your new salary is ${salary}!`))
        .catch(e => api.notifyAdmin(e));
}


P.S. я бы еще бил все это добро на отдельные функции, ибо complexity 10 это все еще много...

import api from 'path/to/api';

export function increaseSalary() {
    return api.getEmployees()
        .then(findEmployeeWithMinSalary)
        .then(calculateNewSalary)
        .then(setEmployeeSalary)
        .then(notifyEmployee)
        .catch(notifyAdmin);
}

function findEmployeeWithMinSalary(employeeData) {
    const [minSalaryEmployee] = employeeData.reduce(minSalaryEmployeeReducer, [null, Infinity]);
    return minSalaryEmployee;
}

// Complexity is 3 - это самая сложная функция
function minSalaryEmployeeReducer([minEmployee, minSalary], employee) {
    const {salary} = employee;
    return (salary < minSalary
        ? [employee, salary]
        : [minEmployee, minSalary]
    );
}

function calculateNewSalary({id, salary}) {
    return {
        id,
        salary: salary * 1.2
    };
}

function setEmployeeSalary({id, salary}) {
    return api.setEmployeeSalary(id, salary);
}

function notifyEmployee({name, id, salary}) {
    return api.notifyEmployee(id, `Hello, ${name}! Congratulations, your new salary is ${salary}!`);
}

function notifyAdmin(e) {
    return api.notifyAdmin(e);
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@twoone
function increaseSalary() {
  return new Promise((resolve, reject) => {
    let minSalaryEmployee = Promise.resolve().then((employeeData) => {
      return { };
    });
    minSalaryEmployee
      .then((data) => {
        let newSalary = Promise.reject();
        newSalary
          .then((newData) => {
            resolve(`Ok`);
          })
          .catch((e) => {
            reject(`Error`)
          });
      })
      .catch(reject);
  });
}

increaseSalary()
  .then(console.log)
  .catch(console.error);
Ответ написан
cr1gger
@cr1gger
Все дороги ведут в Рим — встретимся в Риме!
throw new Exception('Exception')
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы