Является ли ошибкой передача обработчика разрешения / отклонения Promise подфункции? - PullRequest
0 голосов
/ 14 ноября 2018

Учитывая, что у меня есть код, который использует обратные вызовы, и я пытаюсь заключить его в обещания, является ли следующий код ошибкой или антипаттерном?

function getDateAsync(onSuccess, onFailure) {
   ...
}

function getValidDate() {
    return new Promise((resolve, reject) => {
       getDateAsync((date) => {
         checkValidDate(date, resolve, reject);
       }, () => {
         markDateInvalid();
         reject();
       }
    });
}

function checkValidDate(date, resolve, reject) {
   if (isValid(date)) {
      resolve(date);
   } else {
      markDateInvalid();
      reject();
   }
}

function markDateInvalid() { ... }

Это предполагает, что checkValidDate является более сложным и не может быть встроенным, и что markDateInvalid необходимо вызывать в обоих указанных экземплярах.

Есть ли лучший способ написать этот код?

Обновление: ради этого примера мы должны также предположить, что getDateAsync является внешней библиотекой или является иным дорогостоящим и невозможным для преобразования в использование Promises.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

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

function getDateAsPromise() {
    return new Promise(getDateAsync);
    // return new Promise((resolve, reject) => { getDateAsync(resolve, reject); });
}

и с тех пор использовать только обещания:

function getValidDate() {
    return getDataAsPromise().then(date => {
        return checkValidDate(date);
    }, () => {
        markDateInvalid();
        throw; // … some useful value
    });
}

function checkValidDate(date) {
    if (isValid(date)) {
        return date;
    } else {
        markDateInvalid();
        throw; // … some useful value
    }
}

Когда в обратных вызовах возникает исключение (или checkValidDate), это все равно будет работать. С вашим оригинальным подходом - и стандартным кодом на основе обратного вызова - весь процесс завершится с ошибкой.

0 голосов
/ 14 ноября 2018

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

function getDateAsync(onSuccess, onFailure) {
   ...
}

function getValidDate() {
    return new Promise((resolve, reject) => {
       getDateAsync((date) => {
         if (isValidDate(date)) {
            resolve(date);
         } else {
            markDateInvalid();
            reject();
         }
       }, () => {
         markDateInvalid();
         reject();
       }
    });
}

function checkValidDate(date) {
   // return a boolean 
}

function markDateInvalid() { ... }

Имеет смысл сохранить resolve & reject внутри первоначального создания promise и заставить checkValidDate вернуть boolean.

Key Take Away:

Если вам нужно сначала разработать этот странный шаблон, то это хороший признак того, что ваша функция checkValidDate слишком сложна и требует доработки. Ваш код не побеждает цель использования обещаний, но кажется, что он слишком сложный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...