Emisión en lote
Cuando se requiere emitir muchos comprobantes de forma consecutiva (cierre de mes, importación de ventas históricas, generación nocturna), conviene controlar la concurrencia para no saturar el endpoint ni alcanzar el rate limit.
El patrón a continuación procesa una lista de items con un máximo de N emisiones simultáneas, recolectando éxitos y errores sin abortar el lote entero ante una falla puntual.
async function emitirEnLote(items, concurrencia = 5) {
const cola = [...items];
const enProceso = new Set();
const resultados = [];
while (cola.length > 0 || enProceso.size > 0) {
while (cola.length > 0 && enProceso.size < concurrencia) {
const item = cola.shift();
const promesa = emitirFactura(item)
.then(r => resultados.push({ ok: true, data: r }))
.catch(e => resultados.push({ ok: false, error: e, item }))
.finally(() => enProceso.delete(promesa));
enProceso.add(promesa);
}
if (enProceso.size > 0) await Promise.race(enProceso);
}
return resultados;
}Importante: Debe respetarse el rate limit (120 req/min). Con concurrencia 5 y latencia de ~1 s, en ráfaga se alcanzan ~300/min y el rate limit interviene. Corresponde reducir la concurrencia o agregar
await sleep(500)entre emisiones.
Se recomienda combinar esta receta con reintentos exponenciales e idempotencia para que un 429 o 503 no interrumpa el lote.