Расширение `Promise` и изменение подписи` then` - PullRequest
0 голосов
/ 21 декабря 2018

Я хочу расширить Promise и изменить подпись then, чтобы его обратный вызов получил два значения.Я пробовал разные подходы, два из которых задокументированы и протестированы здесь .К сожалению, я получаю различные ошибки, или полученный класс не ведет себя как Обещание.

Подход 1: Упаковка собственного Обещания

export class MyWrappedPromise {
  constructor(data) {
    this.data = data;
    this.promise = new Promise(evaluate.bind(data));
  }

  then(callback) {
    this.promise.then(() => callback(this.data, ADDITIONAL_DATA));
  }

  catch(callback) {
    this.promise.catch(callback);
  }
}

Подход 2: Расширение родных обещаний

export class MyExtendedPromise extends Promise {

  constructor(executor, data) {
    super(executor);
    this.data = data;
  }

  static create(data) {
      return new MyExtendedPromise(evaluate.bind(data), data);
  }

  then(callback) {
    return super.then(() => callback(this.data, ADDITIONAL_DATA));
  }
}

Есть ли у кого-нибудь какие-либо предположения о том, что я делаю неправильно?Не стесняйтесь создавать PR на GitHub.

спасибо

------------------- Редактировать ---------------------

Некоторые дополнительные коды и информация, чтобы сделать приведенный выше код более понятным, не глядя на код и тесты на Github.

evaluate - это просто функция исполнителя Promise.Я извлек его, чтобы сохранить его согласованность во всех моих реализациях и тестах.Он может выглядеть запутанным, но он структурирован таким образом, чтобы имитировать мой «настоящий» проект.

export function evaluate(resolve, reject) {
  const data = this;
  function getPromise(data) {
    return !!data ? Promise.resolve(data) : Promise.reject(new Error("Error"));
  }

  getPromise(data)
    .then(resolve)
    .catch(reject);
}

ADDITIONAL_DATA - это просто строка для имитации второго значения в обратном вызове.Он также извлечен для обеспечения согласованности во всех версиях и тестах.

------------------- Редактировать 2 ---------------------

Ошибки, которые возникают в зависимости от решения

  • catch недоступно
  • Много UnhandledPromiseRejectionWarning: предупреждений, потому что ошибки / отклонения не распространяются правильно.
  • Ошибки / отклонения появляются слишком рано и даже не достигают проверок rejectsв моих тестовых пакетах

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

У вас есть проблемы (особенно с необработанными отклонениями), потому что вы неправильно реализуете интерфейс then.Помните, что .catch(onRejected) - это просто псевдоним для .then(undefined, onRejected), а then с двумя параметрами - это действительный основной метод каждого обещания .

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

then(onFulfilled, onRejected) {
  return super.then(res => onFulfilled(res, this.ADDITIONAL_DATA), onRejected);
  // or `this.promise.then` instead of `super.then`
}
0 голосов
/ 21 декабря 2018

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

Вы имеете в виду что-то подобное?

class MyExtendedPromise extends Promise {

  constructor(executor, data) {
    super(executor);
    this.data = data;
  }

  then(callback, test) {
    console.log('passed new parameter in then:', test);
    console.log('additional data:', this.data);
    return super.then(data => callback(data, test));
  }
}

new MyExtendedPromise((resolve, reject) => {
	setTimeout(() => resolve(true), 2000);
}, 'other additional data').then(data => console.log('my then', data), 'hello world');
...