--- Обобщенная асинхронная функция --- --- Использование в общих чертах выглядит так: --- ```lua --- local multiplyByTwoCallback = nil --- local n = nil --- local function multiplyByTwoAsync(number) --- -- императивно сохраняем/обрабатываем параметр --- n = number --- return function(callback) -- это функция, которая запускает задачу --- multiplyByTwoCallback = callback --- end --- end --- --- local function update(dt) --- --- ждем нужного момента времени... --- --- if multiplyByTwoCallback then -- завершаем вычисление --- local result = n * 2 --- multiplyByTwoCallback(result) -- результат асинхронного вычисления идет в параметр коллбека! --- multiplyByTwoCallback = nil --- end --- end --- --- --- --- потом это можно вызывать так: --- local task = multiplyByTwoAsync(21) --- -- это ленивое вычисление, так что в этот момент ничего не произойдет --- -- запускаем --- task( --- function(result) print(result) end -- выведет 42 после завершения вычисления, т.е. аналогично `task.then((res) => print(res))` на JS --- ) --- --- ``` --- @generic T --- @alias Task fun(callback: fun(value: T): nil): nil --- Возвращает новый Task, который завершится после завершения всех переданных `tasks`. --- --- Значение созданного Task будет содержать список значений `tasks` в том же порядке. --- --- См. также https://api.dart.dev/dart-async/Future/wait.html --- @generic T --- @param tasks Task[] --- @return Task local function wait(tasks) local count = #tasks local results = {} return function(callback) for i, task in ipairs(tasks) do task( function(result) results[i] = result count = count - 1 if count == 0 then callback(results) end end ) end end end --- Последовательно объединяет два `Task` в один. --- @generic T --- @generic R --- @param task Task `Task`, который выполнится первым --- @param onCompleted fun(value: T): Task Конструктор второго `Task`. Принимает результат выполнения первого `Task` --- @return Task local function chain(task, onCompleted) return function(callback) task(function(value) local task2 = onCompleted(value) task2(callback) end) end end return { wait = wait, chain = chain }