Какие преимущества предоставляют некоторые встроенные методы, используя синхронный обратный вызов в качестве аргумента?

avatar
jgrewal
8 августа 2021 в 22:05
63
1
1

Я пытаюсь досконально разобраться в обратных вызовах, и это основная недостающая часть. Я искал этот ответ в Интернете, но большинство из них просто говорят об асинхронных обратных вызовах.

В 1. Почему некоторые встроенные методы, такие как Array.prototype.forEach(), используют synchronous callbacks? Какое преимущество дает эта функция?

Вопрос 2. Как мы решаем, что пора использовать синхронный обратный вызов при реализации собственных пользовательских методов?

Фон:

цикл for of javascript функционально делает то же самое, что и его аналог forEach(), когда речь идет о массивах. Они оба зацикливаются от начала до конца массива. Так зачем нам оба?

Я вижу два очевидных отличия (в общем):

  1. цикл for of может перебирать любой итерируемый объект, forEach специфичен для массивов.
  2. цикл for of позволяет нам использовать ключевые слова continue и break, forEach() не
  3. цикл for of НЕ использует обратный вызов, forEach() ИСПОЛЬЗУЕТ synchronous callback.

Я вижу важность пунктов 1 и 2, но не понимаю пункта 3

В: Какое преимущество дает функция forEach(), принимая в качестве аргумента обратный вызов synchronous?

Ответ, отличный от «он позволяет нам применить функцию к каждому элементу» или позволяет нам «абстрагироваться от логики», был бы действительно полезен, если только ответы на самом деле не настолько очевидны, а я слишком много думаю об этом.

Надеюсь, мой вопрос предельно ясен и однозначен

Источник
VLAZ
8 августа 2021 в 22:09
8

Ответы на самом деле настолько очевидны, и вы слишком много думаете об этом.

charlietfl
8 августа 2021 в 22:10
0

forEach() на самом деле является довольно молодым методом в истории языка и был добавлен поверх циклов for в основном для удобства. Зачем держать оба? Не хотите ломать код, используя старый подход

Kelvin Schoofs
8 августа 2021 в 22:10
1

Основываясь на вашем вопросе, я думаю, вы больше говорите о том, почему определенные синтаксические конструкции (например, циклы for) имеют функции, которыми вы можете их заменить? Имейте в виду, что for of также имеет другие преимущества, например. await поддержка. Один из них — синтаксис JS, другой — просто метод массива.

Bergi
8 августа 2021 в 22:13
6

Не смотрите на forEach. Посмотрите на map, filter, some и тому подобное. Речь идет не о «имении преимущества» — весь метод был бы концептуально невозможен без обратных вызовов!

Dexygen
8 августа 2021 в 22:27
0

for of и forEach do not делают одно и то же

jgrewal
8 августа 2021 в 22:31
0

@Bergi Берги, да, другие методы концептуально невозможны, поэтому они имеют смысл. Но forEach() смутил меня, поэтому я застрял на этом и, следовательно, на вопросе. Тем не менее спасибо за разъяснения!!

jgrewal
8 августа 2021 в 22:36
0

@Dexygen Не могли бы вы уточнить? Что мне не хватает? Я знаю: 1) for of можно использовать для всех итераций, тогда как forEach только для массивов 2) вы можете выйти из for of или пропустить шаг, в отличие от forEach 3) как @Kelvin Schoofs только что напомнил мне (спасибо, Кельвин!!), for of имеет ожидание поддержки forEach нет... что еще я упустил?

Bergi
8 августа 2021 в 22:39
0

@JagnoorGewal forEach также было бы невозможно концептуально - использование обратных вызовов действительно такое же. Конечно, вы можете (и imo даже должны) избегать использования forEach, потому что (в настоящее время) есть лучшие альтернативы, но это не имеет ничего общего с вопросом, почему forEach использует обратный вызов.

jgrewal
8 августа 2021 в 22:39
0

@ВЛАЗ, лол. Забавный ответ

Bergi
8 августа 2021 в 22:42
1

Комментарий @JagnoorGewal VLAZ может быть насмешливым, но это правда - вы слишком много думаете об этом. Вы уже указали цель forEach в своем вопросе. За этим ничего нет.

Ответы (1)

avatar
Evert
8 августа 2021 в 23:22
3

Обратные вызовы по своей сути не являются синхронными или асинхронными. Обратный вызов — это просто функция, которая была передана в качестве аргумента другой функции.

Когда этот обратный вызов вызывается, он должен функционировать, и обычно некоторое другое событие предшествует этому. Если это событие само по себе асинхронно, то вызов также асинхронен.

Это полностью отдельно от forEach и for. Причина существования обоих, вероятно, является комбинацией следующего:

  • for(.. of ..) долгое время не существовало, а for(.. in ..) имеет несколько странное поведение, связанное с прототипами. Это привело к тому, что многие библиотеки реализовали функционал (for)each, в первую очередь jQuery.
  • .
  • Еще одна причина, по которой людям в эпоху jQuery нравился jQuery each, заключается в том, что многие люди не понимали, как ведут себя переменные в области видимости/замыканиях и циклах. Создание функциональной версии позволяет избежать перезаписи переменных замыкания для предыдущих итераций.
  • Наконец, некоторым людям просто нравится идея использования функций для циклов.

Особенно первые две причины сделали $.each популярными до такой степени, что в язык был добавлен родной forEach.

Сегодня меньше причин использовать forEach, потому что:

  • forEach не работает с await.
  • Теперь у нас есть блочные let и const, поэтому перезапись переменных после каждой итерации цикла больше не является проблемой.
  • for(... of ..) делает то, что ожидают люди (нет необходимости в hasOwnProperty).
  • Вы не можете «сломать» с forEach

Некоторые люди по-прежнему предпочитают использовать forEach, если вышеупомянутые пули не вызывают беспокойства. Я не до конца это понимаю, но со стилем не поспоришь.