【问题标题】:How to chain promises together如何将承诺链接在一起
【发布时间】:2017-01-19 10:41:11
【问题描述】:

我正在尝试从一个 Promise 中获取一个值,然后使用该值来解决另一个 Promise。

没有rxjs,它的工作方式如下:

Promise.resolve(1)
  .then(value => Promise.resolve(value + 1))
  .then(value => console.log(value))

输出: 2


这就是我被rxjs 困住的地方:

const observable = Rx.Observable.fromPromise(Promise.resolve(1))
  .map(value => {
    return Rx.Observable.fromPromise(Promise.resolve(value + 1));
  })
const observer = value => console.log(value);
observable.subscribe(observer);

输出:

PromiseObservable {
_isScalar: false,
promise: Promise { 2 },
scheduler: undefined }

【问题讨论】:

  • map 替换为concatMap,但这似乎是一件奇怪的事情。
  • 这绝对看起来很奇怪,但我假设(或希望)实际用例涉及实际上不是静态解决的承诺,所以这样做是有实际理由的。

标签: javascript promise rxjs


【解决方案1】:

observable.map() 应该将观察到的 value 转换为不同的 value。如果你在那里返回一个 observable,你将你的值转换为一个 observable,所以你当然不会得到一个值。从本质上讲,您将您的 observable of values 变成了 observable of observables of values。

如果您想返回一个可观察的并“解包”它,则需要使用concatMap 运算符(通常也称为flatMap):

Rx.Observable.fromPromise(Promise.resolve(1))
    .concatMap(value => {
        return Rx.Observable.fromPromise(Promise.resolve(value + 1));
    })
    .subscribe(value => console.log(value));
// logs out 2

【讨论】:

  • 好先生,感谢您的时间和知识!你是最好的!我爱你!
  • 实际上,请注意 concatMap()flatMap()(在 RxJS 5 中重命名为 mergeMap())是两个非常不同的东西。但是,在这个演示中它并不重要。
【解决方案2】:

你快到了。请记住,Promise 是 Monad,这意味着它们实现了 flatMap,它被 .then() 伪装。使用 RxJS 时,你必须自己扁平化东西:

const observable = Rx.Observable.fromPromise(Promise.resolve(1))
  .switchMap(value => {
    return Rx.Observable.fromPromise(Promise.resolve(value + 1));
  })
const observer = value => console.log(value);
observable.subscribe(observer);
<script src="https://unpkg.com/@reactivex/rxjs/dist/global/Rx.js"></script>

tl;dr; fromPromise 返回一个 Observable 的 Observables。这就是为什么你必须使结果变平的原因。

【讨论】:

  • 很高兴我能帮上忙 ;)
猜你喜欢
  • 1970-01-01
  • 2019-05-24
  • 2016-12-30
  • 1970-01-01
  • 2013-11-25
  • 2020-03-19
  • 2018-02-11
  • 2015-04-15
  • 2023-01-27
相关资源
最近更新 更多