> ## Documentation Index
> Fetch the complete documentation index at: https://docs.markpdf.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Trabajos asíncronos y asincrónicos

> CompletableFuture y manejo de 202 (auto-asíncrono) con SDK de Java.

# Trabajos asíncronos y asincrónicos

SDK de Java expone dos formas independientes de conversión sin bloqueo:

1. **API local asincrónico** (`convertBytesAsync`): su propio código no bloquea el hilo mientras espera la respuesta HTTP, usando `CompletableFuture`.
2. **Trabajos debido a saturación** (`202`): cuando todos los backends del servidor están ocupados, la solicitud se pone en cola en el lado del servidor y responde `202` con un `job_id`. Consulte [`GET /jobs/{id}`](/docs/public/es/api/jobs).

Ambos mecanismos son independientes: puede usar métodos de bloqueo (`convertFile`, `convertBytes`) con `autoPoll` manejando `202` internamente, o usar `convertBytesAsync` para no bloquear su hilo mientras SDK resuelve todo (incluido el sondeo de un trabajo eventual).

## `CompletableFuture` con `convertBytesAsync`

```java theme={null}
CompletableFuture<ConvertResult> future = client.convertBytesAsync(
    data, "report.pdf", ConvertOptions.defaults()
);

future
    .thenAccept(result -> {
        if (result instanceof ConvertResult.Markdown md) {
            System.out.println(md.markdown());
        }
    })
    .exceptionally(err -> {
        Throwable cause = err.getCause() != null ? err.getCause() : err;
        if (cause instanceof MarkpdfException.RateLimitException) {
            System.out.println("Rate limited, retry later");
        } else {
            cause.printStackTrace();
        }
        return null;
    });
```

### Componer varias conversiones en paralelo

```java theme={null}
List<Path> pdfs = List.of(Path.of("a.pdf"), Path.of("b.pdf"), Path.of("c.pdf"));

List<CompletableFuture<ConvertResult>> futures = pdfs.stream()
    .map(path -> client.convertBytesAsync(
        readAllBytesUnchecked(path), path.getFileName().toString(), ConvertOptions.defaults()))
    .toList();

CompletableFuture<Void> all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

all.join(); // espera a que todas terminen
List<ConvertResult> results = futures.stream().map(CompletableFuture::join).toList();
```

<Warning>
  La paralelización agresiva de solicitudes puede desencadenar `429`. Limite la simultaneidad (por ejemplo con `Semaphore` o procesamiento por lotes) si convierte muchos documentos a la vez.
</Warning>

## Empleos por saturación (202)

De forma predeterminada, `convertFile`, `convertBytes`, `convertBytesAsync` y `convertFromUrl` manejan `202` de forma transparente (`ConvertOptions.autoPoll` es `true` de forma predeterminada).

```java theme={null}
// SDK waits and polls automatically (blocking)
ConvertResult result = client.convertFile(Path.of("report.pdf"), ConvertOptions.defaults());
```

### Manual de encuestas

```java theme={null}
ConvertOptions options = ConvertOptions.builder().autoPoll(false).build();
ConvertResult result = client.convertFile(Path.of("report.pdf"), options);

if (result instanceof ConvertResult.Queued queued) {
    System.out.println("En cola: " + queued.job().jobId());

    Job finalJob = client.waitForJob(
        queued.job().jobId(),
        Duration.ofSeconds(5),
        Duration.ofMinutes(10)
    );

    if (finalJob.status() == JobStatus.COMPLETED) {
        String markdown = (String) finalJob.body();
    } else {
        throw new RuntimeException(finalJob.error());
    }
}
```

<Tip>
  En condiciones de carga normales, no verá `202`; solo sucede cuando todos los backends están saturados. `autoPoll: true` (el valor predeterminado) ya lo cubre sin código adicional en la mayoría de los casos.
</Tip>

<Warning>
  Los resultados de los trabajos completados caducan en aproximadamente 1 hora. Si guarda un `jobId` y recibe `404` al consultarlo, reenvíe la conversión original.
</Warning>
