Почему методы массивов могут принимать функцию обратного вызова в качестве параметра, а промисы — нет?

Почему в случае с методами массива, например, <br/> <pre><code class="javascript">const arr = [1,2,3]
arr.map(console.log)</code></pre> <br/> <br/> они выполняются, а в случае с промисами, такими как <br/> <pre><code class="javascript">Promise.all([4,5,6])
.then(data =&gt; console.log)
.catch(err =&gt; console.log)</code></pre> <br/> они не работают, как предусмотрено?
  • 17 октября 2024 г. 15:02
Ответы на вопрос 2
Разберем, почему методы массивов могут принимать функции обратного вызова (коллбеки) и вызывать их, тогда как в случае с промисами поведение отличается.

### Методы массивов

Методы массивов, такие как `.map()`, `.filter()`, и `.forEach()`, принимают функцию обратного вызова в качестве параметра, и эта функция будет вызываться для каждого элемента массива. 

Когда вы пишете:

```javascript
const arr = [1, 2, 3];
arr.map(console.log);
```

Суть в том, что `console.log` — это функция, которая будет вызвана для каждого элемента массива. Внутри метода `map` происходит перебор массива, и для каждого элемента вызывается переданная функция. Таким образом, `console.log` будет выведена для каждого элемента массива (вы увидите в консоли 1, 2, 3).

### Промисы

С другой стороны, промисы работают немного иначе. Промисы используются для обработки асинхронного кода и их методы, такие как `.then()` и `.catch()`, ожидают выполнения асинхронных операций. Когда вы пишете:

```javascript
Promise.all([4, 5, 6])
.then(data => console.log)
.catch(err => console.log);
```

Здесь проблема заключается в том, что `Promise.all` ожидает массив промисов, а вы передаете ему массив чисел. Поскольку числа не являются промисами и не имеют асинхронного поведения, `Promise.all` сразу завершится с успешно выполненной операцией, передав массив `[4, 5, 6]` в `.then()`. Однако в `.then()` у вас записана функция `console.log` без ее вызова (то есть без скобок `()`), то есть вы просто передаете функцию, но не вызываете её. В результате `console.log` не выполняется.

### Исправление

Чтобы исправить этот код и корректно вывести данные в консоль, нужно сделать следующее:

```javascript
Promise.all([Promise.resolve(4), Promise.resolve(5), Promise.resolve(6)])
.then(data => console.log(data))
.catch(err => console.log(err));
```

В этом примере мы оборачиваем числа в промисы с помощью `Promise.resolve`, и теперь `Promise.all` будет работать как задумано. В `.then()` мы также вызываем `console.log(data)` с параметрами, переданными из промиса.

### Резюме

- Методы массивов вызывают переданную функцию для каждого элемента массива.
- Промисы ожидают выполнения асинхронных операций и требуют обработки с участием самих промисов.
- В случае с промисами важно помнить о том, как вы вызываете функции и о том, что они должны быть асинхронными, если это требуется по логике вашего приложения.
Либо 
Promise.all([4, 5, 6])
  .then(console.log)
  .catch(console.log);

либо
Promise.all([4, 5, 6])
  .then(data => console.log(data))
  .catch(err => console.log(err));
Похожие вопросы