您将如何重构重复的“ for-of”循环

时间:2019-01-15 07:41:42

标签: typescript rxjs refactoring

我有以下代码:

  runA() {
    const request = [];
    for (const item of this.items ) {
      request.push(this.getRequestData(item.prop1)); // want to generalize that
    }

    return forkJoin(...request).pipe(x => x);
  }

  runB() {
    const request = [];
    for (const item of this.items ) {
      request.push(this.getOtherData(item.prop2)); // want to generalize that
    }

    return forkJoin(...request).pipe(x => x);
  }

我想重构该代码,以便能够将不同的内容传递到request.push()中,以避免循环重复。我的item包含不同的属性,因此在某些情况下,我需要item.prop1,有时需要item.prop2,所以我的最终代码应类似于:

  run(param) {
    const request = [];
    for (const item of this.items ) {
      request.push(param); // need to get this right
    }

    return forkJoin(...request).pipe(x => x);
  }

  runA() {
    run(this.getRequestData(item.prop1)) // need to get this right
  }

  runB() {
    run(this.getOtherData(item.prop2)) // need to get this right
  }

有什么方法可以在typescirpt中实现?

3 个答案:

答案 0 :(得分:1)

此功能应做您想要的

getAllData(prop){
 return forkJoin(Object.keys(this.items).map(key=>this.getRequestData(this.items[key][prop])))
}

答案 1 :(得分:0)

您的函数有两件事:

  1. 将项目转换为请求数组。
  2. 发送该数组中的所有请求。

将这两件事放在一个函数中很有意义如果该函数每次都在做同一件事,但是函数的第1部分在不同的调用上执行不同的事情(prop1 vs prop2和getRequestData vs getOtherData),因此将其放入函数内部没有任何意义。

为清楚起见,假设您保留了第1部分,则可能决定发送选择器函数作为参数,这将为您提供以下内容:

RunX((item) => {return getRequestData(item.prop1)});
RunX((item) => {return getOtherData(item.prop2)});

这只是使以下代码复杂化了:

let requests = this.items.map((item) => {return getRequestData(item.prop1)});
SubmitRequests(requests);
let requests = this.items.map((item) => {return getOtherData(item.prop2)});
SubmitRequests(requests);

如果处理逻辑实际上重复,则提取方法getProp1Requests();

如果您仍然决定沿此路径前进,请发送选择器函数:

RunX(selector:(Item)=> RequestData){

}

但是您可能不想要使用item [prop],因为这样可以消除类型检查。

答案 2 :(得分:0)

为什么不将getter函数作为参数传递给Run函数呢?

  runAll(getter: (field: string) => any, propName: string) {
    const request = [];
    for (const item of this.items ) {
      request.push(getter(propName));
    }
    return forkJoin(...request).pipe(x => x);
  }

调用方式:

runAll(this.getRequestData, 'prop1Name')
runAll(this.getOtherData, 'prop2Name')

您可以使其具有额外的类型安全性,以确保仅传递有效的Item密钥:

runAll(getter: (field: string) => any, propName: keyof ItemClass)