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 № 1A 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();
})
);