Проблема с асинхронностью [как организовать один коллбек для нескольких асинхронных операций?]

Всем привет! Начал изучать асинхронность, и уже поплыл на первой простой задаче. В общем задача:

Напишите функцию, которая принимает имена двух файлов и вызывает функцию, переданную третьим параметром и передает ей первым аргументом сумму их размеров.

Для получения размера файла необходимо использовать функцию getFileSize(filename, cb).

let fileSizes = {
  testFile1: 65,
  testFile2: 48,
}

function getFileSize(filename, cb) {
  setTimeout(() => cb(fileSizes[filename]), Math.random() * 500);
}

function sumFileSizes(filename1, filename2, cb) {
  //Ваш код...
}

Я прикинул пока что вот так:

function sumFileSizes(filename1, filename2, cb) {
    setTimeout(() => {
        const a = cb(filename1, cb)

        setTimeout(() => {
            const b = a + cb(filename2, cb)

            setTimeout(() => {
                cb(b)
            }, 0)

        }, 0)

    }, 600)
}

sumFileSizes(fileSizes.testFile1, fileSizes.testFile2, getFileSize)

, но выяснилось, что функция getFileSize, которую трогать нельзя вроде как не правильно работает, либо у меня уже мозги не варят (100% второе))


. Ну и само решение я уверен не правильное… Не решите, а направьте на путь истинный пожалуйста)

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

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

Нужно думать в формате. “У меня есть несколько асинхронных операций, нужно выполнить коллбек когда все они закончался. Я буду вести счет асинхронных операций в счетчике (инкрементируя его в каждом колбеке операций) и в каждом коллбеке каждой операции проверять по счетчику последняя ли это операция (зная сколько всего должно быть запущено асинхронных операций). Если операция последняя (счетчик равен общему количеству операций), то выполню общий коллбек с результатами которые нааккумулировались”.


UPD

Не решите, а направьте на путь истинный

Мне лично очень симпотичен этот подход.

1 лайк

спасибо, но суть программы как я понял сначала познакомить с “адом коллбэков”, а потом научить промисами и async/await, чтобы понять почему они так прекрасны для решения самой асинхронности. сложно однако раз сам “ад коллбека” не могу написать, буду грызть дальше)

Тут придется пройти 2 скачка в понимании концепций. И каждый переход непрост, и занимает время. За 1-2 примера, и даже за 1 неделю он может и не произойти. Но париться не надо, в итоге все станет на свои места. Главное думать-работать и высыпаться (я серьезно).

Первый скачок это перейти к пониманию асинхронного кода, после того как научился работать с последовательным, синхронным. Условия-циклы-вызовы функций - примеры синхронного кода, а функции- коллбеки, но не все, - примеры асинхронного. Пример синхронных коллбеков это вызов функций из методов массивов типа forEach и map. Пример асинхронных коллбеков это вызов функций из методов чтения файлов, таймауты-интервалы, обработчики действий пользователя в браузере.

Второй скачок - понять как этот асинхронный код можно описывать в терминах синхронного (async/await).

Про “ад коллбеков”. Есть такой мем, но я искренне не проникся им. Да, можно написать такой код который будет выглядеть как будто вызывается куча вложенных функций. И без ментальной модели того как они работают может показаться что код сложный. Отсутствие ментальной модели работы асинхронных функцийэто характерно для людей, привыкших писать только синхронный код (например php). Но если научиться думать про коллбеки, то “ад коллбеков” перестает быть адом. Этот мем напоминает мне ституацию как если бы вложенные циклы-условия назывались бы “адом скобочек” людьми которые не привыкли их читать и понимать.

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