Как бы вы изменили рефакторинг повторяющегося цикла for-of? - PullRequest
0 голосов
/ 15 января 2019

У меня есть этот код:

  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
  }

Есть ли какой-нибудь способ, которым вы можете достичь этого в typesirpt?

Ответы [ 3 ]

0 голосов
/ 15 января 2019

Ваша функция выполняет две функции:

  1. преобразовать элементы в массив запроса.
  2. Отправить все запросы в этом массиве.

Объединение этих двух вещей в одну функцию имело бы смысл , если бы функция каждый раз выполняла одну и ту же вещь , но часть 1 в вашей функции по-разному выполняет разные вызовы (prop1 против prop2 и getRequestData против 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 (селектор: (Элемент) => RequestData) {

}

Но вы, вероятно, не хотите использовать item [prop], так как это отнимает проверку типов.

0 голосов
/ 15 января 2019

Почему бы просто не передать функцию-получатель в качестве аргумента функции 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) 
0 голосов
/ 15 января 2019

Эта функция должна делать то, что вы хотите

getAllData(prop){
 return forkJoin(Object.keys(this.items).map(key=>this.getRequestData(this.items[key][prop])))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...