使用 RxJS 进行数据验证

Data validation using RxJS

我有以下函数验证 rangeFrom 不优于 rangeTo 并且 rangeFrom 不存在于范围列表中。

如何使用 RxJS 重写它?

const isTagAlreadyExist = (tags, currentTag) => _(tags)
    .filter(x => x.id !== currentTag.id)
    .some(x => _.inRange(currentTag.rangeTo, x.rangeFrom, x.rangeTo))
    .value();

const validateRangeFrom = (tags, currentTag) => {
    const errors = {};

    if (isNumeric(currentTag.rangeFrom)) {    
        if (!_.inRange(currentTag.rangeFrom, 0, currentTag.rangeTo)) {
            errors.rangeFrom = 'FROM_TAG_CANNOT_BE_GREATER_THAN_TO_TAG';
        } else if (isTagAlreadyExist(tags, currentTag)) {
            errors.rangeFrom ='TAG_ALREADY_EXISTS';
        }
    }

    return {
        errors
    };
};

问题是:你想把哪些部分重写成rxjs?据我所知,这是两个 运行 同步的纯函数,我在这里并没有真正看到 rxjs 的用例——当然你总是可以在 rxjs 流中使用你的函数:

const validateRangeFrom$ = (tags, currentTag) => {
    return Observable.of(currentTag)
        .map(tag => validateRangeFrom(tags, tag));
}

validateRangeFrom$(myTags, currentTag)
    .subscribe(errors => console.log(errors));

但是正如您所看到的,如果您只是将它包装在一个流中,这并没有多大意义,有用的响应式编程的本质是,一切都是响应式的,而不是只是一些小部分,所以对于您的示例,您应该首先将 tags$currentTag$ 作为可观察对象 - 让我们假设您拥有这些,然后您可以执行以下操作:

const tags$: Observable<ITag[]>...     // is set somewhere, and emits a new array whenever it is changed
const currentTag$: Observable<ITag>... // is set somewhere and emits the tag whenever a new currentTag is set

const validateRangeFrom$ = Observable
    .combineLatest(tags$, currentTag$, (tags, tag) => ({tags, tag}))
    .map(({tags, tag}) => validateRangeFrom(tags, tag));

validateRangeFrom$.subscribe(errors => console.log(errors));

每当发出新的标签数组或新的 currentTag 是 selected/set 时,这将自动为您触发验证 - 但同样:您的验证方法保持不变 - 即使在反应式编程中必须在某些时候进行验证和逻辑操作,反应部分通常只关注数据流(参见:tags$currentTag$