/ / RxJS Observable.if executa ambas as instruções - javascript, rxjs, observable

RxJS Observable.if executa ambas as instruções - javascript, rxjs, observável

Portanto, sou relativamente novo em RxJs e nos padrões observáveis ​​em geral e atualmente estou lutando para entender alguns dos recursos fornecidos e por que eles se comportam dessa maneira.

Aqui está um snippet de código:

Observable.if( //can also be onErrorResumeNext
() => true,
Observable.fromPromise(
fetch("/"+ locale + "_state.json", {
headers: {
"Accept": "application/json"
},
method: "GET"
}).then(res => {
if (!res.ok) {
throw new Error(res.statusText);
}

return res.json();
})
),
Observable.fromPromise(
fetch("/"+ defaultLocale + "_state.json", {
headers: {
"Accept": "application/json"
},
method: "GET"
}).then(res => {
if (!res.ok) {
throw new Error(res.statusText);
}

return res.json();
})
)
)

Por que ambas as instruções são executadas? Estou fazendo algo / abordando isso da maneira errada ou é um comportamento esperado? Retornando algo mais simples como no exemplo de Observable.if funciona bem, mas tanto quanto eu entendo RxJs é destinado principalmente para dados assíncronos, então o exemplo acima não deveria se comportar da mesma maneira?

Estou ciente de que posso reescrever os comportamentos de Observable.if e Observable.onErrorResumeNext usando Observable.mergeMap e foi isso que acabei fazendo, mas parece que estou perdendo algo aqui.

Respostas:

1 para resposta № 1

A coisa e que promise não é preguiçoso e executa imediatamente. A maneira mais fácil de tornar um cálculo preguiçoso é usar .defer Curtiu isso:

Observable.if( //can also be onErrorResumeNext
() => true,
Observable.defer(() =>
fetch("/"+ locale + "_state.json", {
headers: {
"Accept": "application/json"
},
method: "GET"
}).then(res => {
if (!res.ok) {
throw new Error(res.statusText);
}

return res.json();
})
),
Observable.defer(() =>
fetch("/"+ defaultLocale + "_state.json", {
headers: {
"Accept": "application/json"
},
method: "GET"
}).then(res => {
if (!res.ok) {
throw new Error(res.statusText);
}

return res.json();
})
)
)

.defer irá atualizar automaticamente uma promessa para um observable.


1 para resposta № 2

Você está chamando fetch() duas vezes e passando o resultado para Observable.if(). RxJs não tem capacidade de controlar qual é chamado porque você é já ligando para os dois antes Observable.if() até corre.

O segundo e terceiro parâmetros do seu Observable.if() contém muitos códigos duplicados. Por que não reescrever assim:

Observable.if(() => true, locale, defaultLocale)
.mergeMap(val =>
fetch("/"+ val + "_state.json", {
headers: {
"Accept": "application/json"
},
method: "GET"
}).then(res => {
if (!res.ok) {
throw new Error(res.statusText);
}
return res.json();
})
);