我刚接触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)不会像期望的那样工作,它希望一个承诺本身而不是一个函数,并且Rx.Observable.defer(p1)似乎不像例子传递参数。
谢谢!
类似的问题,但没有数据传递: 使用RxJS链接承诺