У меня есть такой код:
get dislpayHello(): boolean {
let result = false;
console.info('start');
let observable = of(true);
observable.subscribe((display) => {
console.info('set value');
result = true;
});
console.info('finish');
return result;
}
Я всегда думал, что какой бы обратный вызов мы ни поместили в subscribe(), он будет выполняться асинхронно, а поскольку JavaScript является однопоточным, обратный вызов будет выполнен после того, что останется в текущем блоке кода. Итак, в этом примере я ожидаю, что метод dislpayHello
всегда будет возвращать false
, а консоль будет регистрироваться в следующем порядке: «старт», «финиш», «setValue». Однако это не то, что происходит: когда я попробовал, блок подписки выполняется до остального кода. Неужели я все это время просто ошибался?
Как узнать, будет ли подписка осуществлена немедленно или будет отложена? Есть ли какая-либо документация или статьи, которые я мог бы прочитать по этому поводу?
Это заблуждение, что Observables всегда асинхронны, обычно потому, что они часто используются для обработки таких вещей, как HTTP-запросы, которые:
Observable — это лениво вычисляемое вычисление, которое может синхронно или асинхронно возвращать значения от нуля до (потенциально) бесконечных значений с момента его вызова.
Некоторые люди утверждают, что Observables асинхронны. Это неправда.
Рекомендую прочитать https://rxjs.dev/guide/observable, где это проясняется. Выдержки:
Некоторые люди утверждают, что Observables асинхронны. Это неправда. Если вы окружите вызов функции журналами, например:
console.info('before');
console.info(foo.call());
console.info('after');
(где foo
определялось как):
import { Observable } from 'rxjs';
const foo = new Observable((subscriber) => {
console.info('Hello');
subscriber.next(42);
});
foo.subscribe((x) => {
console.info(x);
});
foo.subscribe((y) => {
console.info(y);
});
Вы увидите результат:
"before"
"Hello"
42
"after"
И то же самое поведение с Observables:
console.info('before');
foo.subscribe((x) => {
console.info(x);
});
console.info('after');
И результат:
"before"
"Hello"
42
"after"
Это доказывает, что подписка foo была полностью синхронной, как функция.
Observables могут доставлять значения синхронно или асинхронно.
В чем разница между Observable и функцией? Observables могут «возвращать» несколько значений с течением времени, чего не могут сделать функции.
Более того:
observable.subscribe() означает «дайте мне любое количество значений, синхронно или асинхронно»
По сути, subscribe
может быть синхронным или асинхронным, в зависимости от того, как вы его используете. Если его next
оценивается синхронно, то это синхронно. В противном случае это асинхронно.
С промисами он будет вести себя так, как вы ожидали — даже если промис уже выполнен, обратный вызов, зарегистрированный с помощью
.then
, не будет вызван до следующего «тикания». С наблюдаемыми это не так; если вы.subscribe
обращаетесь к наблюдаемому объекту, который уже отправил значение, обратный вызов вызывается немедленно с этим значением. Обратите внимание, что это не относится только к Angular: stackblitz.com/edit/rxjs-5mwclb?file=index.ts.