Подтвердить что ты не робот

Каковы различия между наблюдаемыми и promises в JavaScript?

Итак, я прочитал, что наблюдаемые стремятся обгонять promises с точки зрения использования в некоторых из предстоящих JavaScript MVC:

В чем разница между наблюдаемыми и promises?

Обновлено: Извинения! удалил ложное выражение.

4b9b3361

Ответ 1

В чем разница между наблюдаемыми и promises?

Проще говоря: обещание разрешает одно значение асинхронно, наблюдаемое разрешает (или испускает) несколько значений асинхронно (со временем).

Конкретные примеры:

  • Обещание: ответ от вызова Ajax
  • Наблюдение: события Click

Более подробную информацию можно найти здесь: http://reactivex.io/intro.html

Я читал, что наблюдаемые стремятся обгонять promises

Вряд ли. Наблюдения могут быть лучшим решением для некоторых проблем, но это не делает устаревшим (w162) (если это то, что вы имеете в виду).

Ответ 2

Promises представляют собой представление 1 будущего значения. Наблюдаемые являются представлением для возможного бесконечного количества значений.

Promises будет инициировать выборку этого значения сразу после создания. Наблюдаемые будут только начинать создавать значения, когда вы подписываетесь на них. (Если это не горячо наблюдаемое, но выходящее за рамки этого вопроса)

Promises предназначены для представления вызовов AJAX. Observables предназначены для представления любых событий: событий, данных из баз данных, данных из ajax-вызовов (возможно, бесконечных) последовательностей и т.д.

Ответ 3

Promises предлагает очень упрощенный механизм обратного вызова, где Rx предлагает мощную абстракцию по асинхронному программированию. Observable представляет поток данных, который мы можем затем применить к операторам, чтобы определить, как обрабатывать поступающие данные.

Если все, что вам нужно сделать, это сделать HTTP-запрос, а затем обновить компонент пользовательского интерфейса, то использовать Promise может быть достаточно.

Однако большинство приложений, как правило, имеют более сложные потребности, чем это (даже если это не очевидно при первом). Например, используя наш HTTP-запрос, давайте посмотрим, как моделирование этого как Наблюдаемого и использование некоторых операторов Rx могут нам помочь:

-Если HTTP-запрос инициируется действием пользователя, мы можем опасаться отпустить несколько HTTP-запросов (представьте, что пользователь вводит текст в поле поиска). Мы не хотим запускать запрос на каждое нажатие клавиши, поэтому мы можем захотеть Throttle наш поиск, чтобы мы только запускали запрос, если пользователь перестает печатать на 300 мс. Кроме того, если пользователь вводит слово, ждет 300 мс и добавляет другой символ, хорошо сработает последующий HTTP-запрос. С Promises, wed, вероятно, сталкивается с состоянием гонки, поскольку мы не можем контролировать порядок, в котором хорошо принимаем ответы, и мы не можем отменить старые запросы. Rx разрешает это, позволяя нам Переключить между потоками, который вызывает Dispose на старых подписях запросов, которые нам больше не нужны. Мы также могли бы отфильтровать любые недопустимые входные данные поиска, например Где длина поиска меньше 3 символов.

-Поддержка для обработки тайм-аутов/обработки ошибок. Допустим, наш HTTP-запрос завершился неудачно, Rx позволяет нам легко Повторить выполнение запроса.

-Позволяет сказать, что несколько частей нашего приложения должны сделать один и тот же HTTP-вызов, мы, вероятно, не хотим, чтобы он делал вызов более одного раза. Мы можем выявить наши наблюдаемые для нескольких потребителей и использовать Replay, чтобы гарантировать, что вызов выполняется один раз, и результат кэшируется для последующих подписчиков. Мы можем даже поставлять TimeSpan для воспроизведения, что дает нам истечение срока действия кэша.

- Мощная абстракция при поточной передаче через использование планировщиков, что позволяет нам управлять concurrency. Еще лучше, мы можем использовать Test Schedulers в наших модульных тестах для контроля времени, что позволяет нам имитировать тайм-ауты, условия гонки и т.д.

Вот несколько примеров для демонстрации того, что возможно. В рамках Rx существует множество операторов, которые обслуживают все типы сценариев, а композитность Rx означает, что вы можете легко комбинировать операторов для определения необходимого вам поведения. Его также легко создать своих собственных операторов многократного использования (например, RetryAfterDelay).

Таким образом, Rx может делать все, что может сделать Promises, и гораздо больше. Я подозреваю, что в ближайшие пару лет будет продолжаться переход к Rx вместо Promises.

Для дальнейшего чтения я бы рекомендовал взглянуть на раздел "Наблюдаемые" в Angular 2 guide.

Ответ 4

как сказано в Angular 2 Guid

Преобразование в Обещание часто является хорошим выбором, если вы хотите получить один кусок данных. Итак, когда вы получите данные, все готово.

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

например, в поисковом компоненте. Когда пользователь вводит имя в поле поиска, вы будете повторять HTTP-запросы по этому поисковому запросу.

Последовательность запрос-отмена-новый-запрос сложно реализовать с помощью Promises, но легко с Observables.

так что если ваш компонент получает данные только с одним запросом, то это хороший выбор для использования Promise но если у него есть цепочка запроса request-cancel-new, вы должны использовать observable

Ответ 5

Наблюдаемые часто сравнивают с обещаниями. Вот некоторые ключевые отличия:

Наблюдаемые являются декларативными; расчет не начинается до подписки. Обещания выполняются немедленно при создании. Это делает наблюдаемые полезными для определения рецептов, которые можно запускать, когда вам нужен результат.

Наблюдаемые дают много значений. Обещания дают один. Это делает наблюдаемые полезными для получения нескольких значений с течением времени.

Наблюдаемые различают цепочку и подписку. Обещания имеют только предложения .then(). Это делает наблюдаемые полезными для создания сложных рецептов преобразования, которые будут использоваться другой частью системы, без необходимости выполнения работы.

Observables subscribe() отвечает за обработку ошибок. Обещания подталкивают к ошибкам ребенка. Это делает наблюдаемые полезными для централизованной и предсказуемой обработки ошибок.

Лучшее объяснение на английском на официальном сайте:

https://angular.io/guide/comparing-observables

Ответ 6

Когда вы правильно понимаете Observable, различия с Promise довольно очевидны.

Лучший способ демистифицировать замысловатую концепцию - реализовать ее с нуля. Вот почти чисто функциональная реализация Observable и пример, который не будет работать с Promise s:

/*** Observable type ***/

// type constructor (of a product type)

const proType = name => cons => {
  const f = (k, ...args) =>
    Object.defineProperties({["run" + name]: k}, {
      [Symbol.toStringTag]: {value: name},
      [Symbol("args")]: {value: args}
    });

  return cons(f);
};

// value constructor

const Observable = proType("Observable")
  (Observable => k => Observable(k));

/*** Observer factory ***/

const Observer = observer => {
  let isUnsubscribed = false;

  return {
    next: function(x) {
      if (isUnsubscribed)
        throw new Error("unsubscribed");

      else {
        try {
          return observer.next(x);
        }

        catch(e) {
          isUnsubscribed = true;
          this.cancel();
          throw e;
        }
      }
    },

    error: function(e) {
      if (isUnsubscribed)
        throw new Error("unsubscribed");

      else {
        try {
          return observer.error(e);
        }

        catch(e_) {
          isUnsubscribed = true;
          this.cancel();
          throw e_;
        }
      }
    },

    complete: function() {
      if (isUnsubscribed)
        throw new Error("unsubscribed");

      else {
        try {
          const r = observer.complete();
          this.cancel();
          return r;
        }

        catch(e) {
          isUnsubscribed = true;
          cancel();
          throw e;
        }
      }
    }
  };
};

/*** combinators + auxiliary functions ***/

const subscribe = observable => handlers => {
  const observer = Observer(handlers),
    cancel = observable.runObservable(observer);

  observer.cancel = cancel;
  return cancel;
};

const obsMap = f => observable =>
  Observable(observer => {
    const mapObserver = {
      next: x => observer.next(f(x)),
      error: e => observer.error(e),
      complete: () => observer.complete()
    };

    return observable.runObservable(mapObserver);
  });

/*** main ***/

// create an Observable instance

const numStream = Observable(observer => {
  let i = 0;

  const timer = setInterval(() => {
    observer.next(i++);
  }, 1000);
  
  return () => clearTimeout(timer);
});

// map a function over it

const squaredNumStream =
  obsMap(x => x * x) (numStream);

// run the observable

const cancel = subscribe(squaredNumStream) ({
  next: x => console.log(x),
  error: e => console.error(e),
  complete: () => console.log("finished")
});

// cancel it

setTimeout(cancel, 11000);