Какое неожиданное поведение наблюдается у RxJS с асинхронными функциями и toPromise? - PullRequest
0 голосов
/ 12 мая 2018

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

const Observable = require("rxjs").Observable;
let i = 0;
const x = new Observable((o) => {
    setInterval(() => o.next(++i), 1000);
});

(async () => {
    while (true) {
        try {
            console.log("loop");
            console.log("value", await x.toPromise());
        } catch (e) {
            console.log(e);
        }
    }
})();
x.subscribe((value) => {
    console.log("subscribe", value);
});

Результат этого кода:

loop
subscribe 2
subscribe 4
subscribe 6
subscribe 8
subscribe 10
subscribe 12
subscribe 14

Что случилось?

Это работает так же с этим вариантом использования toPromise

function a() {
    x.toPromise().then((value) => {
        console.log("promise", value);
        a();
    }).catch((e) => {
        console.log("error", value);
    });
}
a();

1 Ответ

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

toPromise() выполняется на Наблюдаемой после ее завершения. Поскольку ваша наблюдаемая никогда не завершается, она не выполняется. Используйте take(1), чтобы заставить его излучать значение до завершения наблюдаемого.

const Observable = require("rxjs").Observable;
let i = 0;
const x = new Observable((o) => {
    setInterval(() => o.next(++i), 1000);
});

(async () => {
    while (true) {
        try {
            console.log("loop");
            console.log("value", await x.take(1).toPromise());//here
        } catch (e) {
            console.log(e);
        }
    }
})();
x.subscribe((value) => {
    console.log("subscribe", value);
});

Выход:

loop
subscribe 2
value 1
loop
subscribe 4
value 5
loop
subscribe 7
value 9
loop
subscribe 11
value 14

Что касается значений:

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

...