84 lines
2.9 KiB
Lua
84 lines
2.9 KiB
Lua
--- Обобщенная асинхронная функция
|
||
---
|
||
--- Использование в общих чертах выглядит так:
|
||
--- ```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<T> 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<T[]>
|
||
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<T> `Task`, который выполнится первым
|
||
--- @param onCompleted fun(value: T): Task<R> Конструктор второго `Task`. Принимает результат выполнения первого `Task`
|
||
--- @return Task<R>
|
||
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
|
||
}
|