我尝试使用RxJS替换下一段代码(jsbin):
function parseRequestUrl(url) {
var newUrl;
if ((newUrl = testThatUrlIsOrigin1(url)) !== url) {
return doSomething(newUrl);
}
if ((newUrl = testThatUrlIsOrigin2(url)) !== url) {
return doSomething(newUrl);
}
if ((newUrl = testThatUrlIsOrigin3(url)) !== url) {
return doSomething(newUrl);
}
}
我能够使用RxJS(jsbin)实现的东西,但在这种情况下,我需要调用一个函数两次,其中"过滤表达式"是真的
function parseRequestUrl(url) {
var newUrl = url;
var observer = Rx.Observable.of(testThatUrlIsOrigin1, testThatUrlIsOrigin2, testThatUrlIsOrigin3);
observer.first(getUrlFunc => getUrlFunc(url) !== url).map(getUrlFunc => getUrlFunc(url)).subscribe(createdUrl => newUrl = createdUrl)
return doSomething(newUrl);
// And so on
}
RxJS可以满足我的要求吗?
答案 0 :(得分:4)
我认为RxJs不适合这项工作。它最适合处理异步数据流。我认为更好的方法是将所有测试函数放在一个数组中并循环遍历它们。像这样:
const tests = [testThatUrlIsOrigin1, testThatUrlIsOrigin2, testThatUrlIsOrigin3];
function parseRequestUrl(url) {
for (const test of tests) {
const newUrl = test(url);
if (newUrl === url) continue;
return newUrl;
}
}
function testThatUrlIsOrigin1(url) {
console.log("try testThatUrlIsOrigin1");
if (url === 'origin1') {
console.log("Pass testThatUrlIsOrigin1");
return "First If";
}
return url;
}
function testThatUrlIsOrigin2(url) {
console.log("try testThatUrlIsOrigin2");
if (url === 'origin2') {
console.log("Pass testThatUrlIsOrigin2");
return "Second If";
}
return url;
}
function testThatUrlIsOrigin3(url) {
console.log("try testThatUrlIsOrigin3");
if (url === 'origin3') {
console.log("Pass testThatUrlIsOrigin3");
return "Third If";
}
return url;
}
parseRequestUrl('origin2')
如果你想获得所有OO,你也可以实现Chain of Responsibility设计模式。
修改强> 既然你想看看如何在RxJs中做到这一点,这里有一个简化版本:
function test(a, b) {
return a === b ? `${a} test` : b;
}
const tests = [
test.bind(null, 1),
test.bind(null, 2),
test.bind(null, 3),
];
const value = 2;
Rx.Observable.from(tests)
.map(x => x(value))
.filter(x => x !== value)
.take(1)
.subscribe(
x => { console.log(x); },
null,
() => { console.log('completed'); }
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.5/Rx.min.js"></script>