Асинхронность и ожидание с сопрограммами
Создайте вспомогательные функции async() и await(), приостанавливающие и возобновляющие сопрограммы.
«Асинхронность и ожидание с сопрограммами» — бесплатный урок Lua Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Идея асинхронности и ожидания
Асинхронность и ожидание — это модель программирования, в которой асинхронные операции выглядят как синхронный код. В Lua корутины предоставляют механизм уступки управления и возобновления, позволяющий естественно реализовать эту модель.
Функция await
await(future) приостанавливает текущую корутину и сохраняет обратный вызов, который возобновит её после завершения будущего результата.
local function await(future)
local co = coroutine.running()
future.onComplete = function(result)
coroutine.resume(co, result)
end
return coroutine.yield()
endОбёртка асинхронной функции
async(fn) оборачивает функцию, чтобы она выполнялась в новой корутине под управлением планировщика.
local function async(fn)
return function(...)
local co = coroutine.create(fn)
local ok, err = coroutine.resume(co, ...)
if not ok then print("async error:", err) end
return co
end
endПростой объект будущего результата
Будущий результат представляет ожидаемый результат. Завершите его позже — и он возобновит все ожидающие корутины.
local function newFuture()
local f = {done=false, value=nil, waiters={}}
f.complete = function(val)
f.done = true; f.value = val
for _, cb in ipairs(f.waiters) do cb(val) end
end
f.andThen = function(cb)
if f.done then cb(f.value)
else f.waiters[#f.waiters+1] = cb end
end
return f
endИспользование await
Пишите асинхронный код, выглядящий последовательным, хотя внутри он уступает управление и возобновляется.
local fetchData = async(function(url)
local result = await(httpGet(url)) -- yields
local parsed = await(parseJSON(result)) -- yields again
print("Got:", parsed.name)
end)
fetchData("http://example.com/api")Передача ошибок
Передавайте ошибки через будущий результат: если операция завершается неудачно, возобновляйте корутину с признаком ошибки и сообщением об ошибке.
local function awaitSafe(future)
local co = coroutine.running()
future.onComplete = function(ok, result)
coroutine.resume(co, ok, result)
end
return coroutine.yield()
endПоследовательное и параллельное выполнение
Используйте await последовательно для зависимых операций. Для независимых операций запустите обе корутины и дождитесь общего будущего результата.
Шаблон Promise.all
Запускайте несколько асинхронных задач и ждите их полного завершения, используя будущий результат со счётчиком.
local function all(futures)
local results = {}
local count = #futures
local combined = newFuture()
for i, f in ipairs(futures) do
f:andThen(function(v)
results[i] = v
count = count - 1
if count == 0 then combined.complete(results) end
end)
end
return combined
endОтмена
Реализуйте отмену, помечая корутину как отменённую до её возобновления. Корутина проверяет этот признак и досрочно возвращает результат.
Интеграция с вводом-выводом
Интегрируйте неблокирующий ввод-вывод: когда вызов ввода-вывода должен был бы заблокироваться, уступайте управление и регистрируйте обратный вызов для возобновления после появления данных.
Сравнение со стилем обратных вызовов
Асинхронный код с ожиданием и корутинами значительно понятнее вложенных обратных вызовов. Обработка ошибок с помощью pcall также проще, чем передача параметров ошибок в обратные вызовы.
Вопрос об асинхронности и ожидании
Что делает await(future) в асинхронной системе на основе корутин?
Повторение: асинхронность и ожидание с корутинами
Реализуйте асинхронность и ожидание с помощью корутин, оборачивая асинхронные операции в будущие результаты, которые после завершения возобновляют приостановленную корутину. В результате код выглядит последовательным, хотя на самом деле не блокируется.
Часто задаваемые вопросы
Урок «Асинхронность и ожидание с сопрограммами» бесплатный?
Да — полный текст урока «Асинхронность и ожидание с сопрограммами» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Асинхронность и ожидание с сопрограммами»?
Создайте вспомогательные функции async() и await(), приостанавливающие и возобновляющие сопрограммы. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Асинхронность и ожидание с сопрограммами»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Создание простого цикла событий
- Асинхронность и ожидание с сопрограммами
- Шаблоны, подобные обещаниям
- Неблокирующий ввод-вывод с luasocket