Javascript RxJS承诺组合(传递数据)

Javascript RxJS承诺组合(传递数据),javascript,functional-programming,rxjs,frp,ramda.js,Javascript,Functional Programming,Rxjs,Frp,Ramda.js,我是Rx的新手,我发现很难找到关于编写承诺的文档,比如第一个承诺的数据被传递到第二个承诺,等等。这里有三个非常基本的承诺,对数据的计算并不重要,只是必须使用前面承诺中的数据来实现异步 const p1 = () => Promise.resolve(1); const p2 = x => { const val = x + 1; return Promise.resolve(val); }; const p3 = x => { const isEven = x

我是Rx的新手,我发现很难找到关于编写承诺的文档,比如第一个承诺的数据被传递到第二个承诺,等等。这里有三个非常基本的承诺,对数据的计算并不重要,只是必须使用前面承诺中的数据来实现异步

 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));
 };
实现我所说的构图的传统方法是:

 pl().then(p2).then(p3).then(console.log);
我最喜欢的实现是Ramda的composeP和pipeP:

R.pipeP(p1, p2, p3, console.log)()
似乎Rx可能能够非常流利地处理这种情况。然而,到目前为止,我发现的最接近于RxJS与异步(库)的比较如下:

concatMap看起来很有希望,但是上面的代码看起来非常可怕。我的示例也遇到了问题,因为Rx.Observable.fromPromise(p1)不能像它期望的那样工作,而不是一个函数,并且Rx.Observable.defer(p1)似乎不像示例那样传递参数

谢谢

类似问题,但未传递数据:

我没有全部阅读,但是如果您想实现与
pl().then(p2.then(p3.then)(console.log)相同的功能
,使用
p
函数返回承诺,您可以执行以下操作(示例)

或者更对称:

 var chainedPromises$ = 
     Rx.Observable.just()
             .flatMap(p1)
             .flatMap(p2)
             .flatMap(p3);
现在,如果您想通过
fromCallback
fromCallback
执行顺序回调,您可以执行以下操作:

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
作为替换。

您的承诺必须包装在函数中吗?仅当您在承诺链外部内联定义了一个承诺,或者使用const p1=new promise((resolve,reject)=>{})之类的内容进行观察时才可以这样做它将立即开始评估,无法从先前执行的承诺中接收数据。或者我对即时评估的理解是错误的?也许是有用的——例如使用rxjs6链接承诺——我有点希望得到一个稍微高一点的抽象,类似于flatMapAll(p1、p2、p3)。如果通过映射生成一系列承诺,例如const ps=map((x)=>promiseDfsReadFileCurriedSothatitDessomethingWithPreviousFileData(x),['1.txt','2.txt','3.txt',]),则特别有用;Rx.Observable.just().flatMapAll(…ps);(只是伪代码)。但这绝对是一个可管理的解决方案,而且很可能有一种方法可以通过映射fromPromise之类的东西来实现这一点。谢谢也没有测试第二个代码示例,但是第一个代码示例就像charmyou自己可以做的
flatMapAll
一样工作<代码>flatMapAll::Rx.Observable->[a->a]->Rx.Observable
flatMap all=(源代码,fn_数组)->fn_数组.reduce((acc,fn)->acc.flatMap(fn,源代码)
。在js中,
Rx.Observable.prototype.flatMapAll=function(fn_数组){source=this;return…}
yep,也有类似的结果。下面是我写的
constflatmapall=(…fns)=>fns.reduce((acc,fn)=>acc.flatMap(fn),Rx.Observable.just());flatMapAll(p1、p2、p3)。订阅(console.log)
。谢谢你的帮助。还有,第一个例子是什么语言?看起来非常接近Haskell它是伪代码,但sintax是从Haskell得到启发的,至少是类型声明。
 var chainedPromises$ = 
     Rx.Observable.just()
             .flatMap(p1)
             .flatMap(p2)
             .flatMap(p3);
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)