Pular para o conteúdo

22 · Expressões Temporais

Agendamento: every, after e timeout

Loop periódico com `every`, disparo único com `after`, e cancelamento por prazo com `timeout`.

Nesta página

Zolo tem três construções de agendamento integradas à linguagem. Todas são palavras reservadas — não use every, after ou timeout como nomes de variável; prefira intervalo, agendado, prazo ou limite.

every — loop periódico

every <dur> { ... } repete o corpo no intervalo indicado. É um laço infinito por design: encerre-o com break quando a condição de saída for atingida.

Contador com break após 3 iterações; soma acumulada que para ao atingir o total desejado.

05-every.zolo
Playground
// Feature: periodic loop with `every <dur> { ... }`

// Syntax: `every <duration> { body }` — repeats the body at the given

// interval. It is a keyword (not a variable name).

// When to use: health-checks, polling, animation, metrics, any

// task that needs to run repeatedly on a fixed interval.


var tick = 0

// Runs 3 times (short interval for the demo) and exits with `break`.

every 50ms {
  tick = tick + 1
  print("tick #{tick}")
  if tick >= 3 {
    break
  }
}

print("done")

// expected:

// tick #1

// tick #2

// tick #3

// done


// Another example: summing until a total is reached.

var total = 0
every 25ms {
  total = total + 10
  if total >= 30 {
    break
  }
}
print("total = {total}")
// expected: total = 30

after — disparo único

after <dur> { ... } agenda a execução do bloco uma única vez, após o atraso. É fire-and-forget: não bloqueia o fluxo principal. Use sleep depois para manter o programa vivo até o callback disparar.

Três after coexistindo; ordem de disparo determinada pelo scheduler.

06-after.zolo
Playground
// Feature: schedule one execution with `after <dur> { ... }`
// Syntax: `after <duration> { body }` — fire-and-forget; the block
// runs **once** after the delay. It is a keyword.
// When to use: one-shot callbacks, timers, expirations, single
// reminders. Unlike `every`, it does not repeat.

print("scheduling...")

// Block runs 50ms later — does not block the main flow here.
after 50ms {
  print("fired after 50ms!")
}

// Multiple `after` may coexist.
after 100ms {
  print("fired after 100ms!")
}

after 25ms {
  print("this one was first")
}

print("scheduled, waiting...")

// Keep the program alive long enough to see the firings.
sleep 200ms
print("end")
// expected (approximate order — depends on the scheduler):
// scheduling...
// scheduled, waiting...
// this one was first
// fired after 50ms!
// fired after 100ms!
// end

timeout — prazo de cancelamento

timeout <dur> { ... } retorna um objeto { ok, value, error }. Se o bloco concluir dentro do prazo, ok é true e value contém o retorno. Se expirar, ok é false e error é "timeout". Como o scheduler é cooperativo, o cancelamento só ocorre em pontos de yield (sleep, IO, etc.).

Caminho feliz com retorno dentro do prazo; nota sobre o comportamento cooperativo e alternativa de nome para a variável de prazo.

07-timeout.zolo
Playground
// Feature: cancel work that takes too long with `timeout`

// Syntax: `timeout <dur> { body }` returns `Result<T, TimeoutError>`.

// When to use: network calls, uncertain IO, tasks that need a

// fail-safe. Cooperative: only fires at a yield point.


// Happy path: body finishes within the deadline.

let result_ok = timeout 100ms {
  return 42
}
match result_ok {
  Result::Ok(value) => print("ok: {value}"),
  Result::Err(error) => print("err: {error.message}"),
}

// expected: ok: 42


// IMPORTANT: `timeout` is a reserved keyword — you cannot use it

// as a variable name. Use `deadline`, `limit`, `dur`, etc. instead.

let limit = 5000
print("using '{limit}' instead of 'timeout' as the name")

// Timeout case: body takes longer than the limit and is interrupted.

// Note: cooperative — the deadline is checked each time the body

// yields (e.g. via `sleep`), so slow work needs checkpoints: a body

// that never yields, or yields once and then finishes, runs to

// completion and returns Ok. A yielding body also needs a task to

// yield to, so run the block inside `spawn` (the top-level main

// thread cannot yield); the task prints after the main chunk ends.

spawn {
  let result_slow = timeout 30ms {
    for _ in 0..10 {
      sleep 20ms  // each sleep is a checkpoint where the deadline can fire

    }
    return "too late"
  }
  match result_slow {
    Result::Ok(value) => print("ok: {value}"),
    Result::Err(error) => print("err: {error.message}"),
  }
}
// expected: err: timeout

Desafio

Combine every 100ms com um after 500ms que seta uma flag de parada. O every deve verificar a flag e chamar break quando ela for verdadeira.

Índice global

Encontre seu caminho pela Zolo

Experimente uma ideia

Comece por aqui

9 resultados

9 resultados

enespt-br