如何保持RxJs干燥

时间:2018-08-11 00:38:25

标签: angular rxjs ngrx

干燥(不要重复自己)

假设我的应用中经常使用以下代码:

observable$.pipe(
  tap(value => console.log(value)),
  map(value => value * 5),
  ... more repeated stuff
)

假设代码5的某些部分的值不同,但其他所有部分都相同。我可以以某种方式对其进行功能化/执行某些操作以使其可重用以避免复制粘贴问题吗?

我可以做这样的事情吗?

observable$.pipe(
  getReusedOperators(7), // this would pipe to all above operators using 7 instead of 5
  tap((value) => console.log('im not reused and my value is', value)),
  ....
)

这里最好的方法是什么?抱歉,我的问题不是很好,但希望您能明白。

2 个答案:

答案 0 :(得分:6)

可管道运算符要记住的事情是,它们只是具有可观察值并返回可观察值的函数,因此您可以轻松地创建可重用的运算符组合,如下所示:

function getReusedOperators(factor) {
  return source => source.pipe(
    tap(value => console.log(value)),
    map(value => value * factor),
  );
}

对于未参数化可重用组合的情况,您可以只使用静态pipe函数进行组合。有关某些示例,请参见我的Combining Operators文章。

答案 1 :(得分:2)

如果希望将某些可重用的内容添加到管道中,则可以编写一个返回OperatorFunction(在rxjs中定义)的方法。管道操作员将一个或多个OperatorFunction作为参数。

以下是我在应用程序中使用的其中一个示例:

public void loadReleaseData(final int refresh) {
    if (getActivity() == null) {
        Log.d(TAG, "Fragment filter " + mFilter + " [fragment is null]");
        return;
    } else {
        Log.d(TAG, "Updating fragment: " + mFilter);
    }

    if (AppUtil.doesInternetWork(getActivity())) {
        // Viewpager does not load all fragments in memory, contents will be null
        mDatabaseLoading.setVisibility(View.VISIBLE);
        mUpcomingList.setVisibility(View.VISIBLE);
        mEmptyTextInfo.setVisibility(View.GONE);
        noInternetTxt.setVisibility(View.GONE);
        mUpcomingPageLayout.setClickable(false);
        // ... Queries from firebase
    }
}

此OperatorFunction将一种类型的数组映射到另一种类型的数组,然后对结果进行排序。

它可以与例如,

一起使用
  /*
   * Returns an "OperatorFunction", suitable for passing to rx.pipe(),
   * that maps a Role[] to a sorted FormRole[] (sorted by role name)
   */
  public rolesToSortedFormRolesMapper(): OperatorFunction<Role[], FormRole[]> {
    return map((roles: Role[]) => roles.map((role) =>
        new FormRole(role.role, role.name, false)
      ).sort((lhs, rhs) => (lhs.name.localeCompare(rhs.name)))
    );
  }

当然,您也可以将其他运算符放入管道中。