RxJS Promise 组合(传递数据) [英] RxJS Promise Composition (passing data)

查看:17
本文介绍了RxJS Promise 组合(传递数据)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Rx 的新手,我发现很难找到有关撰写承诺的文档,以便将第一个承诺中的数据传递到第二个承诺中,依此类推.这是三个非常基本的 promise,对数据的计算并不重要,重要的是必须使用前一个 promise 中的数据进行异步操作.

I'm brand new to Rx and am finding it difficult to find documentation on composing promises such that data from the first promise is passed into the second and so on. Here's three very basic promises, the calculations on the data aren't important, just that something async has to be done using data from the previous promise.

 const p1 = () => Promise.resolve(1);
 const p2 = x => { const val = x + 1; return Promise.resolve(val); };
 const p3 = x => {
      const isEven = x => x % 2 === 0;
      return Promise.resolve(isEven(x));
 };

实现我所说的构图的传统方法:

The traditional way to achieve the composition I'm talking about:

 pl().then(p2).then(p3).then(console.log);

我最喜欢的实现是 Ramda 的 composeP 和 pipeP:

My favorite implementation is Ramda's composeP and pipeP:

R.pipeP(p1, p2, p3, console.log)()

似乎 Rx 可能能够非常流畅地处理这种情况.但是,到目前为止我发现的最接近的是从 RxJS 到异步(库)比较这里 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/mapping/async/comparing.md:

It seems likely Rx might be able to handle this kind of situation pretty fluently. However, the closest I've found so far is from the RxJS to async (library) comparison here https://github.com/Reactive-Extensions/RxJS/blob/master/doc/mapping/async/comparing.md:

 var Rx = require('rx'),
     fs = require('fs'),
     path = require('path');
 var file = path.join(__dirname, 'file.txt'),
     dest = path.join(__dirname, 'file1.txt'),
     exists = Rx.Observable.fromCallback(fs.exists),
     rename = Rx.Observable.fromNodeCallback(fs.rename),
     stat = Rx.Observable.fromNodeCallback(fs.stat);
 exists(file)
    .concatMap(function (flag) {
     return flag ?
         rename(file, dest) :
         Rx.Observable.throw(new Error('File does not exist.'));
    })
    .concatMap(function () {
        return stat(dest);
    })
   .forEach(
      function (fsStat) {
          console.log(JSON.stringify(fsStat));
      },
      function (err) {
          console.log(err);
      }
    );

concatMap 看起来很有希望,但上面的代码看起来非常可怕.我的例子也有问题,因为 Rx.Observable.fromPromise(p1) 不会工作,因为它期望一个承诺本身,而不是一个函数,而且 Rx.Observable.defer(p1) 似乎没有传递像示例.

concatMap seems promising, but the above code looks pretty horrific. I was also having trouble with my example because Rx.Observable.fromPromise(p1) won't work as it expects a promise itself, not a function, and Rx.Observable.defer(p1) doesn't seem to pass parameters like the example.

谢谢!

类似的问题,但没有数据传递:使用 RxJS 链接 promise

Similar question but without data passing: Chaining promises with RxJS

推荐答案

我没看全,但是如果你想达到和 pl().then(p2).then(p3) 一样的.then(console.log);p 是返回承诺的函数,你可以做类似的事情(例如 这里)

I did not read all of it, but if you want to achieve the same as pl().then(p2).then(p3).then(console.log);, with p being function returning promises, you could do something like (example here)

Rx.Observable.fromPromise(p1())
             .flatMap(function(p1_result){return p2(p1_result);})
             .flatMap(function(p2_result){return p3(p2_result);})

或者更对称:

 var chainedPromises$ = 
     Rx.Observable.just()
             .flatMap(p1)
             .flatMap(p2)
             .flatMap(p3);

现在,如果您想执行通过 fromCallbackfromNodeCallback 包装的顺序回调,您可以执行以下操作:

Now if you want to execute sequentially callback wrapped through fromCallback or fromNodeCallback, you could do something like :

function rename (flag){
  return flag
          ? rename(file,dest).flatMap(return Rx.Observable.just(dest))
          : Rx.Observable.throw(new Error('File does not exist.'));
}

Rx.Observable.just(file)
             .flatMap(exists)
             .flatMap(rename)
             .flatMap(stat)

后一个代码未经测试,所以如果可行,请让我更新.最后一条评论,如果在每个点您只产生一个值(如承诺),这应该有效.如果你有多个文件而不是一个,使用 flatMap 你可能会遇到排序问题(如果顺序对你很重要),所以在这种情况下,你可以使用 concatMap 作为替换.

The latter code is untested, so keep me updated if that works. Last comment, this should work if at each point you only have one value produced (like a promise). If you would have several files instead of one, with flatMap you might get ordering issues (if order matters to you), so in that case, you could use concatMap as a replacement.

这篇关于RxJS Promise 组合(传递数据)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆