Как использовать синхронный API с асинхронным подклассом - PullRequest
0 голосов
/ 21 мая 2018

У меня есть небольшой пакет утилит npm Utilities, который я хочу использовать для двух моих кодовых баз, AppA и AppB.

Утилиты предоставят класс с некоторыми функциями, и онэто работа AppA и AppB для создания подкласса, где это необходимо.

class Utilities {

  processData(data, callback)  {
    var result = this.validateData(data);
    // This will fail for AppB, because validateData returns a promise.
    var length = result.length;
    callback(length);
  }

  validateData(data) {
    // Must be subclassed
  }

}

AppA:

class AppA extends Utilities {
  validateData(data) {
    return [1, 2, 3];
  }
}

AppB:

class AppB extends Utilities {
  validateData(data) {
    // returns a Promise
    return AsyncMethods.checkData(data);
  }
}

Пакет Utilities написан синхронно, как и приложение A. Однако AppB требует взаимодействия с некоторыми асинхронными методами внутри validateData.Мой класс Utilities, однако, не знает, что у потребителя есть асинхронный API.

Я могу с легкостью менять как Утилиты, так и AppB, но не AppA.Поэтому мне нужен способ написания утилит таким образом, чтобы он мог работать как в синхронной, так и в асинхронной средах.

В идеале я бы просто изменил AppB и заставил его ждать:

class AppB {
  async validateData(data) {
    var result = await AsyncMethods.checkData(data);
    return result;
  }
}

Однакоэто все равно возвращает объект Promise, а не фактический результат, потому что это асинхронная функция.

Еще одно решение, которое не дотягивает до работы, - это ожидание внутри processData в Utilities:

  async processData(data, callback)  {
    var result = await this.validateData(data);
    var length = result.length;
    callback(length);
  }

Однакоэто нарушает работу AppA, поскольку его реализация не является асинхронной, и я не могу изменить AppA.

Есть ли здесь какие-либо варианты?Возможно, способ сделать все функции await по умолчанию?

Вот скрипка: https://jsfiddle.net/1ptoczh7/3/

Примечание для AppB: результат не определен.Мне нужно иметь возможность получить оба выхода без изменения AppA.

1 Ответ

0 голосов
/ 22 мая 2018

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

Написать две разные утилиты.Вы почти наверняка закончите с этим в любом случае.Разложите общий код в общий модуль (посмотрите, как этот ответ , как эффективно это сделать).Асинхронная функциональность просто слишком отличается от синхронной.

В вашем примере это, скорее всего, будет выглядеть так:

function getLength(result) {
  return result.length;
}

class Utilities {
  processData(data) { // returns int
    return getLength(this.validateData(data));
  }
  // abstract validateData(data): Result
  // to be overwritten in subclass
}
class AsyncUtilities {
  processData(data) { // returns Promise<int>
    return this.validateData(data).then(getLength);
  }
  // abstract validateData(data): Promise<Result>
  // to be overwritten in subclass
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...