Как сделать самовызывающуюся рекурсивную стрелочную функцию?

написал вот такой код:

(function doCount(i) {
  console.log(i);
  setTimeout(() => {
    if (i < 100) {
      doCount(++i);
    }
  }, 15)
}(0))
но не нравится "function" хочется как то покороче покрасивее)) может быть даже избавиться от именования.


Ответы (1 шт):

Автор решения: Stanislav Volodarskiy

Вот аналог на стрелочных функциях. Его пришлось завернуть в анонимную функцию чтобы не засорять глобальное пространство имен:

(() => {
    const doCount = i => {
        console.log(i);
        if (i < 100) {
            setTimeout(() => doCount(i + 1), 15);
        }
    };
    doCount(0);
})();

Не очень красиво. Но function expression позволяет именовать и вызывать функцию в одном операторе. Для стрелочных функций такого сервиса нет: чтобы использовать имя функции в рекурсивном вызове, определение функции должно быть присвоено какой-то переменной. Громоздко.

Безымянный рекурсивный вызов делается с помощью Y combinator. Идея в том что передать в функцию её саму в качестве аргумента. Тогда её можно вызывать рекурсивно, не ссылаясь ни на какие глобальные имена:

((f, i) => f(f, i))((f, i) => {
    console.log(i);
    if (i < 100) {
        setTimeout(() => f(f, i + 1), 15);
    }
}, 0);

Если предыдущий код кажется запутанным, вот его расшифровка с глобальными именами. Так будет проще разобраться. Важное: каждое глобальное имя в коде используется только один раз, что позволяет все три оператора собрать в один как в предыдущем примере:

const YCombinator = (f, i) => f(f, i);

const doCount = (f, i) => {
    console.log(i);
    if (i < 100) {
        setTimeout(() => f(f, i + 1), 15);
    }
};

YCombinator(doCount, 0);
→ Ссылка