考虑以下流:
{
"query": {
"regexp":{
"product": "*card*"
}
}
}
假设 const oEmailValid$ = oEmailInput$
.map(_catchInputCtrlValue)
.map(_isStringNotEmpty)
.map(...)
.map(...)
.map(...)
.map(...)
.subscribe((predicate) => console.log(predicate))
返回_isStringNotEmpty
,所以我不想继续使用流,但仍希望在订阅函数上接收false
的返回值,在这种情况下是_isStringNotEmpty
。
如何获得它?
为了澄清,我的意思是,请考虑以下false
代码:
Haskell
结果我得到(Just 3) >>= (\_ -> Just 4) >>= (\_ -> Just 7) >>= (\_ -> Nothing) >>= (\_ -> Just 10)
,因为第4次计算返回Nothing
。
答案 0 :(得分:1)
JavaScript没有管道或撰写运算符,因此组合函数的语法可以是:
update: (store, { data: { createLink } }) => {
const data = store.readQuery({
query: ALL_LINKS_QUERY
})
data.allLinks.push(createLink)
store.writeQuery({ query: ALL_LINKS_QUERY, data })
}
以下是一些例子的组合:
compose(arrayOfFunctions);
如果您想使用自定义运算符,可以使用sweet.js编译代码。这些自定义运算符在IDE中显示为语法错误,因此如果您想要编程功能,那么可以查看ELM或Fable。
答案 1 :(得分:1)
Folktale有一个很好的Maybe monad。 https://github.com/folktale/data.maybe
function find(collection, predicate) {
for (var i = 0; i < collection.length; ++i) {
var item = collection[i]
if (predicate(item)) return Maybe.Just(item)
}
return Maybe.Nothing()
}
var numbers = [-2, -1, 0, 1, 2]
var a = find(numbers, function(a){ return a > 5 })
var b = find(numbers, function(a){ return a === 0 })
a.map(function(x){ return x + 1 })
// => Maybe.Nothing
b.map(function(x){ return x + 1 })
// => Maybe.Just(1)
答案 2 :(得分:0)
你可以试着像这样破解:
const NOTHING = {};
const wrapMaybe =
fn =>
x =>
(x!==undefined && typeof x.then === "function")
?x.then(wrapMaybe(fn))
:(x === NOTHING)?NOTHING:fn(x)
const source = Rx.Observable.from([1,2,3,4,5]);
//wrap each map function in a maybe
const example = source
.map(wrapMaybe(val => console.log("map:",1,val) || val + 10))
.map(wrapMaybe(val => console.log("map:",2,val) || Promise.resolve(NOTHING)))
.map(wrapMaybe(val => console.log("map:",3,val) || val + 10))
;
//wrap the source in an object that has mm (maybe map) function
const wrapSource =
source => {
source.mm =
function(fn){
var ret = this.map(wrapMaybe(fn));
ret.mm = this.mm;
return ret;
}
;
return source;
}
;
const example2 = wrapSource(source)
.mm(val => console.log("mm:",1,val) || val + 20)
.mm(val => console.log("mm:",2,val) || NOTHING)
.mm(val => console.log("mm:",3,val) || val + 20)
;
example.subscribe(val => console.log(val));
example2.subscribe(val => console.log(val));
答案 3 :(得分:0)
对于这种情况,我想到了几种解决方案。但是,如果你真的在寻找像Haskell那样的东西,那么Folktale(如用户7128475建议)或Sanctuary有可能的实现。
第一个需要使用<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
和.filter
,但这只适用于.defaultIfEmpty
是0 - 1流的情况。
oEmailInput$
如果你想将它应用于0 - *流,这个解决方案也可以在flatMap内部工作。
const oEmailValid$ = oEmailInput$
.map(_catchInputCtrlValue)
.map(_isStringNotEmpty)
.filter(isValid => isValid) // or .filter(Boolean)
.map(...)
.map(...)
.map(...)
.map(...)
.defaultIfEmpty(false)
.subscribe((predicate) => console.log(predicate))
更一般的解决方案是再次使用flatMap,它也适用于0 - *流:
const oEmailValid$ = oEmailInput$
.map(_catchInputCtrlValue)
.map(_isStringNotEmpty)
.flatMap(isValid => Observable.of(isValid)
.filter(Boolean)
.map(...)
.map(...)
.map(...)
.map(...)
.defaultIfEmpty(isValid)
)
.subscribe((predicate) => console.log(predicate))
就个人而言,我认为流不是这类问题的最佳代表。 Streams最好的模型动作\行为与单一的行为目标,现在你原来的例子的目的不清楚,似乎有独立但相等的分支。流通常应该模拟数据如何通过一系列期望的操作来组成单个行为。这就是我怀疑Shuhei Kagawa试图进入的地方。例如,我使用表示执行以下操作的表单的流:
const oEmailValid$ = oEmailInput$
.map(_catchInputCtrlValue)
.flatMap(input => _isStringNotEmpty(input)
? Observable.of(input)
.map(...)
.map(...)
.map(...)
.map(...)
: Observable.of(false)
)
.subscribe((predicate) => console.log(predicate))
,onFormSubmit$
.map(_validateData)
.tap(console.log) // along the lines of your subscribe function
.tap(showErrors)
.tap(updateFormState)
.filter(form => form.isValid)
.subscribe(_postData)
的结果将是一般形状,如:
_validateData
这样,像showErrors这样的步骤可以映射错误数组,如果它是空的或需要条件测试则不会中断。
答案 4 :(得分:-1)
因为您只使用map
,这意味着所有验证都是同步进行的,所以我只想编写一个函数来同时处理所有验证。
function validate(validators) {
return input =>
validators.every(validator => validator(input));
}
const oEmailValid$ = oEmailInput$
.map(validate([
_catchInputCtrlValue,
_isStringNotEmpty,
...
]))
.subscribe((predicate) => console.log(predicate));
我相信尽可能多地编写纯函数并使用Stream或类似Monad的东西,只有当你真正需要它时才会很好,就像在Haskell中一样。