我是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到async(库)比较,这里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)将无法工作,因为它需要一个promise本身,而不是一个函数,而Rx.Observable.defer(p1)似乎没有传递像例.
谢谢!
类似的问题,但没有数据传递: 链接承诺与RxJS
我没有读这一切,但是如果你想要达到相同的pl().then(p2).then(p3).then(console.log);
,与p
是函数返回的承诺,你可以这样做(例如这里)
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);
现在,如果你想通过fromCallback
or 执行顺序回调fromNodeCallback
,你可以做类似的事情:
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
作为替代品.