Почему три разных варианта одной и той же функции ведут себя иначе?

Пожалуйста, объясните, почему три варианта одной и той же функции ведут себя по-разному. Вот пример кода, который работает корректно:

```javascript
// Есть массив объектов:
[{
  name: 'dismissal_reason_id',
  options: lookupDismissalReasonsByGroup()
}]

// Сама функция lookupDismissalReasonsByGroup:
function lookupDismissalReasonsByGroup () {
  const method = dismissalReasons.lookupDismissalReasonsByGroup

  return function(_, props) {
    return function ({ text }) {
      const id = props && props.dismissal_reason_group_id ? props.dismissal_reason_group_id : null
      return method({ id, search: text, limit: 100 })
    }
  }
}

// Далее в Vue 2 в цикле создаются компоненты и вызывается функция options:
const options = this.field.options(this.currentValue, this.value)
```

Этот код работает правильно, но до этого я пробовал другие подходы, которые не дали желаемого результата, и я не полностью понимаю причины. Пожалуйста, объясните, что может быть не так и как эти варианты можно исправить.

Кроме того, вот второй подход, в котором параметры передаются явно в функцию `lookupDismissalReasonsByGroup`:

```javascript
[{
  name: 'dismissal_reason_id',
  options: (_, props) => lookupDismissalReasonsByGroup(props)
}]

function lookupDismissalReasonsByGroup (props) {
  const method = dismissalReasons.lookupDismissalReasonsByGroup

  return function() {
    return function ({ text }) {
      const id = props && props.dismissal_reason_group_id ? props.dismissal_reason_group_id : null
      return method({ id, search: text, limit: 100 })
    }
  }
}

const options = this.field.options(this.currentValue, this.value)
```

Однако в этом случае запрос на сервер даже не уходит.
  • 10 января 2025 г. 17:43
Ответы на вопрос 2
Давайте разберемся, что происходит в вашем коде и почему разные подходы могут вести себя по-разному.

## Первый подход

### Структура

```javascript
function lookupDismissalReasonsByGroup () {
  const method = dismissalReasons.lookupDismissalReasonsByGroup

  return function(_, props) {
    return function ({ text }) {
      const id = props && props.dismissal_reason_group_id ? props.dismissal_reason_group_id : null
      return method({ id, search: text, limit: 100 })
    }
  }
}
```

В этом варианте функция `lookupDismissalReasonsByGroup` возвращает другую функцию, которая получает два аргумента: `_` и `props`. Эта финальная функция, в свою очередь, возвращает еще одну функцию, которая будет вызываться с объектом, содержащим поле `text`. 

#### Как это работает:

1. Вы вызываете `lookupDismissalReasonsByGroup()` и получаете внутреннюю функцию, которая ожидает два параметра.
2. При вызове `this.field.options(this.currentValue, this.value)`, вы передаете текущие значения, которые будут переданы внутрь функции.
3. В конечном итоге вы вызываете метод `lookupDismissalReasonsByGroup` с нужными параметрами.

## Второй подход

### Структура

```javascript
options: (_, props) => lookupDismissalReasonsByGroup(props)
```

В этом случае вы изменяете состав функции. Ваш код вызывает `lookupDismissalReasonsByGroup(props)`, однако, вы не учитываете, что результатом этой функции является еще одна функция, поэтому вы не вызываете саму финальную функцию, которую возвращает `lookupDismissalReasonsByGroup`.

#### Основные проблемы:

1. **Вернувшаяся функция**: В вашем втором подходе вы вызываете `lookupDismissalReasonsByGroup(props)`, но это возвращает функцию, которая ожидает вызвать с объектом, содержащим `text`. Однако вы эту возвращенную функцию сразу не вызываете. Это и есть причина, по которой запрос на сервер не уходит — вы не вызываете ту функцию, которая на самом деле инициирует запрос.

Чтобы исправить это, вам нужно либо вызвать возвращаемую функцию, либо изменить логику так, чтобы вы обрабатывали параметры по-другому. 

### Исправленный вариант второго подхода

Вот один из способов исправить второй подход:

```javascript
options: (_, props) => {
  const lookupFunction = lookupDismissalReasonsByGroup(props);
  return (params) => lookupFunction(params);
}
```

В этом случае, когда вы вызовете `this.field.options(this.currentValue, this.value)`, вы получите функцию, которая затем ожидает объект с полем `text`, что в свою очередь и инициирует запрос к серверу.

## Вывод

Вывод в том, что в JavaScript очень важно понимать, что происходит с функциями и какие функции на самом деле вызываются. Всегда проверяйте, возвращаете ли вы функцию и вызываете ли ее затем, как ожидается. В вашем случае, отсутствие вызова возвращаемой функции во втором подходе является причиной того, что запрос на сервер не отправляется.
Насколько я вижу, в первом варианте, lookupDismissalReasonsByGroup - это функция (1), которая возвращает функцию (2), которая возвращает функцию (3) 

И в массиве объектов поле options - это результат вызова (1), т.е. (2)
Затем в строке
const options = this.field.options(this.currentValue, this.value)
вызывается (2) и в options записывается (3)

В случае же второго варианта lookupDismissalReasonsByGroup получается совершенно такая же по вложенности функций. Но в массиве объектов теперь в поле options - не результат вызова (1), а другая функция (0), которая внутри себя вызывает (1) и возвращает её результат (2)
И получается, что далее в
const options = this.field.options(this.currentValue, this.value)
вызывается (0) и в options записывается (2), т.е. не та же функция, как в первом примере
Похожие вопросы