【问题标题】:Idiomatic if-else chain with rx/rxjs带有 rx/rxjs 的惯用 if-else 链
【发布时间】:2016-11-16 11:34:21
【问题描述】:

我有一段在命令式语言中可能看起来像这样的流程:

if (something1()) {
  try {
    return loadDataFrom1();
  } catch (err) { }
}

if (something2()) {
  try {
    return loadDataFrom2();
  } catch (err) { }
}

if (something3()) {
  try {
    return loadDataFrom3();
  } catch (err) { }
}

return someSafeDefault();

条件不是互斥的。有可能something1()something2() 都为真,在这种情况下loadDataFrom2() 应该在loadDataFrom1() 失败时发生。

现在我需要使用 rxjs 5 来实现这一点,条件以及处理 Observables 的操作。

我可以通过创建 Observables 并在各处订阅来轻松实现回调地狱等价物,但由于许多显而易见的原因,这很糟糕。

什么是好的、惯用的方法?

【问题讨论】:

  • 条件是互斥的(即 if...else if....else if?)
  • @Meir 查看更新。
  • somethingX()loadDataFromX() 是什么?如果这些不返回 Observables,那么您可以只使用 map()concatMap(),具体取决于您想要做什么。
  • 条件和操作都在处理(异步)observables。

标签: rxjs rxjs5


【解决方案1】:

转换为 Promise 并使用 async/await 作为一种可能的解决方案,但使用纯 rxjs 可以执行以下操作:

var something1: () => Observable<boolean>;
var something2: () => Observable<boolean>;
var something3: () => Observable<boolean>;

type MyData = { data: string };
var loadDataFrom1: () => Observable<MyData>;
var loadDataFrom2: () => Observable<MyData>;

var first = something1()
    .take(1)
    .filter(something => something ==  true)
    .flatMap(() => loadDataFrom1())
    .catch(e => Observable.of({ message: e }))
    // Take one result, this will be either the sucessful result from lodaData or the err or object { message: e }
    .take(1);

var second = something2()
    .take(1)
    .filter(something => something ==  true)
    .flatMap(() => loadDataFrom2())
    .catch(e => Observable.of({ message: e }))
    // Take one result, this will be either the sucessful result from lodaData or the err or object { message: e }
    .take(1);

var third = something3()
    .take(1)
    .filter(something => something ==  true)
    .flatMap(() => loadDataFrom2())
    .catch(e => Observable.of({ message: e }))
    // Take one result, this will be either the sucessful result from lodaData or the err or object { message: e }
    .take(1);

var safeDefault = Observable.of({data: 'My safe result'});

var result = Observable
    .concat(first, second, third, safeDefault)
    // filter away all exception results
    .filter(data => data.message == null)
    // take only one actuall valid result  
    .take(1);

【讨论】:

    猜你喜欢
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 2017-12-29
    • 1970-01-01
    • 2016-08-30
    • 2023-03-14
    • 2023-03-27
    相关资源
    最近更新 更多