Javascript RxJS承诺组合(传递数据)
我是Rx的新手,我发现很难找到关于编写承诺的文档,比如第一个承诺的数据被传递到第二个承诺,等等。这里有三个非常基本的承诺,对数据的计算并不重要,只是必须使用前面承诺中的数据来实现异步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
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.ObservableflatMap 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)