0Pricing
Lua Academy · Урок

Асинхронность и ожидание с сопрограммами

Создайте вспомогательные функции 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 — локальная установка не требуется.

Все уроки этого курса

  1. Создание простого цикла событий
  2. Асинхронность и ожидание с сопрограммами
  3. Шаблоны, подобные обещаниям
  4. Неблокирующий ввод-вывод с luasocket
← Назад к Lua Academy