0Pricing
Lua Academy · Lección

resume y yield

Intercambie datos entre la persona que llama y la coroutine mediante resume/yield.

resume y yield es una lección gratuita de Lua Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Lua Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Lua Academy incluye 4 lecciones en total.

Pasar valores a una corrutina

Los argumentos que se pasan al primer coroutine.resume se convierten en los parámetros de la función que constituye el cuerpo de la corrutina. Los argumentos que se pasan a las reanudaciones posteriores son los valores que devuelve la llamada a coroutine.yield() que pausó la corrutina.

local co = coroutine.create(function(a, b)
  print("received:", a, b)        -- 10  20
  local c = coroutine.yield()     -- pauses
  print("after yield:", c)        -- 30
end)

coroutine.resume(co, 10, 20)  -- first call: passes a,b
coroutine.resume(co, 30)      -- subsequent: passed to yield

Valores de yield

Los valores que se pasan a coroutine.yield(val1, val2) se convierten en los valores de retorno de la llamada a coroutine.resume() que quedó pausada en yield. Por tanto, yield «devuelve» valores a quien realiza la llamada.

local co = coroutine.create(function()
  coroutine.yield(1, "hello")
  coroutine.yield(2, "world")
  return 3, "done"
end)

local ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  1  hello

ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  2  world

ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  3  done

Comunicación bidireccional

Las corrutinas permiten una comunicación bidireccional real: quien realiza la llamada pasa datos mediante resume, la corrutina los procesa y devuelve resultados mediante yield. Cada operación resume/yield es un intercambio síncrono.

local co = coroutine.create(function(x)
  while true do
    x = coroutine.yield(x * x)  -- yield x^2, get next x
  end
end)

coroutine.resume(co)  -- start (x=nil initially)
local ok, sq
ok, sq = coroutine.resume(co, 3); print(sq)  -- 9
ok, sq = coroutine.resume(co, 5); print(sq)  -- 25
ok, sq = coroutine.resume(co, 7); print(sq)  -- 49

Productor-consumidor

El patrón clásico con corrutinas: el productor produce los elementos de uno en uno mediante yield; el consumidor reanuda el productor cada vez que necesita el siguiente elemento. Ninguno se adelanta al otro: es una sincronización perfecta.

local function producer(items)
  return coroutine.create(function()
    for _, item in ipairs(items) do
      coroutine.yield(item)
    end
  end)
end

local pro = producer({"apple","banana","cherry"})

-- Consumer drives the loop
while true do
  local ok, item = coroutine.resume(pro)
  if not ok or item == nil then break end
  print("consumed:", item)
end

Pipeline con corrutinas

Encadene varias corrutinas como un pipeline. Cada etapa lee de la anterior y produce valores para la siguiente mediante yield. La etapa final impulsa el pipeline al reanudar la última etapa, lo que se propaga hacia atrás por toda la cadena.

local function source(items)
  return coroutine.wrap(function()
    for _, v in ipairs(items) do coroutine.yield(v) end
  end)
end

local function filter(iter, pred)
  return coroutine.wrap(function()
    for v in iter do
      if pred(v) then coroutine.yield(v) end
    end
  end)
end

local function map(iter, fn)
  return coroutine.wrap(function()
    for v in iter do coroutine.yield(fn(v)) end
  end)
end

local pipeline = map(filter(source({1,2,3,4,5,6}),
  function(n) return n%2==0 end),
  function(n) return n*n end)

for v in pipeline do io.write(v.." ") end
print()  -- 4 16 36

Corrutinas para simular asincronía

Sin hilos del sistema operativo, las corrutinas pueden simular operaciones asíncronas: use yield mientras se «espera» y reanude la corrutina cuando el «resultado» esté listo. Un planificador reanuda la corrutina con el resultado.

local scheduler = {}
local current = nil

local function await(key)
  coroutine.yield(key)  -- tell scheduler what we need
  return coroutine.yield()  -- wait for result
end

local co = coroutine.create(function()
  local data = await("fetch:users")
  print("Got users:", data)
end)

-- Start coroutine
local ok, want = coroutine.resume(co)
print("Coroutine wants:", want)  -- fetch:users
-- Simulate delivering the result:
coroutine.resume(co, {{name="Alice"},{name="Bob"}})

yield dentro de una función

Puede usar yield desde cualquier función llamada por una corrutina, no solo desde la función de nivel superior. El yield asciende por todas las llamadas anidadas hasta llegar a resume. Esto se denomina «pila de llamadas suspendida».

local function yieldTwice(label)
  coroutine.yield(label .. ":1")
  coroutine.yield(label .. ":2")
end

local co = coroutine.create(function()
  yieldTwice("A")
  yieldTwice("B")
end)

for i = 1, 4 do
  local ok, v = coroutine.resume(co)
  print(v)
end
-- A:1, A:2, B:1, B:2

Las corrutinas no son hilos

Las corrutinas de Lua no son hilos del sistema operativo. Solo se ejecuta una corrutina a la vez; no hay expropiación ni paralelismo. Todas las corrutinas comparten un único hilo del sistema operativo. Para lograr un paralelismo real, necesita varios estados de Lua en hilos del sistema operativo independientes.

-- This is NOT parallel - interleaved execution
local function task(name, n)
  for i = 1, n do
    print(name, i)
    coroutine.yield()
  end
end

local t1 = coroutine.create(function() task("A", 3) end)
local t2 = coroutine.create(function() task("B", 3) end)

-- Must explicitly schedule:
for _ = 1, 3 do
  coroutine.resume(t1)
  coroutine.resume(t2)
end
-- A1, B1, A2, B2, A3, B3 (interleaved, NOT parallel)

Estado después de resume

Compruebe el estado de la corrutina para decidir si debe reanudarla otra vez. Una corrutina que ha terminado (ha retornado desde su cuerpo) está «muerta»; al reanudarla se devuelve false con un error. Compruebe siempre el estado antes de reanudarla en bucles.

local co = coroutine.create(function()
  for i = 1, 3 do coroutine.yield(i) end
end)

while coroutine.status(co) ~= "dead" do
  local ok, val = coroutine.resume(co)
  if ok and val ~= nil then
    print("val:", val)
  end
end
-- val: 1, val: 2, val: 3

Varios yield en un solo resume

Una sola llamada a coroutine.resume ejecuta la corrutina hasta el siguiente yield o hasta que termina. No puede hacer que una corrutina produzca varios yield en una sola reanudación: cada yield la suspende y espera la siguiente reanudación.

local co = coroutine.create(function()
  local x = coroutine.yield("first")
  print("got:", x)
  local y = coroutine.yield("second")
  print("got:", y)
end)

local _, v1 = coroutine.resume(co)         -- starts, yields "first"
print("yielded:", v1)                       -- first
local _, v2 = coroutine.resume(co, "a")   -- passes "a", yields "second"
print("yielded:", v2)                       -- second
coroutine.resume(co, "b")                   -- passes "b", coroutine ends

Comprobación rápida

¿En qué se convierten los valores que se pasan a coroutine.yield(v1, v2)?

Resumen: resume y yield

Resumen:

  • Argumentos de la primera reanudación → parámetros del cuerpo de la corrutina
  • Argumentos de las reanudaciones posteriores → valores devueltos por el yield() anterior
  • Argumentos de yield → valores devueltos por el resume() que activó ese yield
  • Bidireccionalidad: cada resume/yield es un intercambio
  • El yield funciona desde cualquier función anidada
  • Las corrutinas son cooperativas, no paralelas

Preguntas frecuentes

¿La lección «resume y yield» es gratis?

Sí — el texto completo de «resume y yield» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Lua Academy, actualiza a CoddyKit PRO. El curso de Lua Academy incluye 4 lecciones en total.

¿Qué aprenderé en «resume y yield»?

Intercambie datos entre la persona que llama y la coroutine mediante resume/yield. Practicas Lua Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Lua Academy?

No se requiere experiencia previa. Lua Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «resume y yield»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Lua Academy?

Sí. Cada lección de Lua Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Creación de coroutines
  2. resume y yield
  3. Estado de las coroutines
  4. Patrón productor-consumidor
← Volver a Lua Academy