Существуют ли различия между .then(functionReference) и .then(function (value) {return functionReference (value)})?

Учитывая именованную функцию, используемую для обработки значения Promise

function handlePromise(data) {
  // do stuff with `data`
  return data
}

a) Передача названной функции handlePromise в качестве ссылки на .then()

promise.then(handlePromise)

b) Используя анонимную или именованную функцию как параметр для .then() и возвращающую именованную функцию handlePromise с Promise значением в качестве параметра в теле анонимной или именованной функции, переданной в .then()

promise.then(function /*[functionName]*/(data) {return handlePromise(data)})

Вопросы

  • Существуют ли различия между шаблонами а) и б)?

  • Если ответ на вопрос 1. да, каковы различия, которые должны быть рассматривается при использовании любого шаблона?

Ответ 1

Можно создать случай, когда есть разница, когда аргумент не передается, но он растягивается и обычно вы должны передавать f, а не function(x) { return f(x); } или x => f(x), потому что он более чист.

Вот пример, вызывающий разницу, логика состоит в том, что функции, которые принимают параметры, могут вызывать побочные эффекты с такими параметрами:

function f() {
   if(arguments.length === 0) console.log("win");
   else console.log("Hello World");
}
const delay = ms => new Promise(r => setTimeout(r, ms)); // just a delay
delay(500).then(f); // logs "Hello World";
delay(500).then(() => f()) // logs "win"

Ответ 2

Нет разницы, function(x){return f(x)} === f.

Для получения дополнительной информации вы можете прочитать о eta-conversion в исчислении лямбда.

Ответ 3

Логика

С логической точки зрения нет ничего, что могло бы отделить их.

Источник

В контексте исходного кода и стиля мой личный вкус противоречит объявлениям встроенных функций, поскольку их труднее читать (при чтении кода другого пользователя, когда я читаю свое собственное произведение искусства LOL)

Отладка

С точки зрения отладки при глубоком вложенности его сложнее отлаживать, когда у вас длинная трассировка стека анонимных вызовов.

Производительность

С точки зрения производительности он зависит от браузера. Без существенных различий с Firefox. Использование Chrome Canary 60 и всех версий ранее. Объявление объявлений анонимной функции значительно медленнее после первого вызова, чем определенные операторы функций, и выражения функций. Это верно как для традиционных, так и для стрелочных функций.

Сравнение двух альтернатив и синхронизации только цикла while

var i,j;
const f = a => a;
j = i = 10000;

while(i--) f(i);  // timed loop


while(j--) (a=>a)(j); // timed loop

Предварительно определенная функция выполняется на 870% быстрее, чем встроенная функция.

Но я еще не видел, чтобы кто-либо использовал promises в критическом критически важном коде, разница во времени на тестовом компьютере (win10 32bit) составляет 0,0018 мкс (*) для f(i) и 0.0157 мкс для (a=>a)(i)

(*) μs обозначает микросекунды 1/1,000,000th секунды

Заключение

Различия незначительны и незначительны, более важны личный вкус и стиль, чем что-либо еще. Если вы работаете в команде, используйте стиль, описанный в руководстве по стилю, если вы руководите проектом или работаете самостоятельно, используйте то, с чем вам наиболее удобно.

Случай края, как показано в BenjaminGruenbaum ответить, я не считаю правильным, поскольку он явно вызывает f() в then(()=>f()) без аргумента. Это то же самое, что и const ff = () => f(); delay(0).then(ff), а не quirk того, как определена функция.

Ответ 4

Есть действительно одно основное отличие, хотя и не столь важное, чего на самом деле следует избегать. Если вы вызываете handlePromise() как непосредственно внутри, тогда() вам не разрешается добавлять внешние параметры. Если вы вызываете его внутри функции, которая находится внутри, тогда .then( (result) => handle(result, someOtherParam) ), то вы можете добавить "someotherparam" для вызова. Это удобно, если у вас больше дерева вызовов, хотя я бы избегал этого и передавал его целую цепочку promises.

TL;DR; первый из них вызывается с результатами .then() в качестве параметров, последний является эластичным в том, что вы хотите пройти дальше.