Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

215
Visualizações
Agregue varias llamadas y luego separe el resultado con Promise

Actualmente tengo muchas llamadas simultáneas idénticas a mi backend, que difieren solo en un campo de ID:

 getData(1).then(...) // Each from a React component in a UI framework, so difficult to aggregate here getData(2).then(...) getData(3).then(...) // creates n HTTP requests... inefficient function getData(id: number): Promise<Data> { return backend.getData(id); }

Esto es un desperdicio ya que hago más llamadas. Me gustaría mantener mis llamadas getData() , pero luego agregarlas en una sola llamada getDatas() a mi backend, luego devolver todos los resultados a las personas que llaman. Tengo más control sobre mi backend que el marco de la interfaz de usuario, por lo que puedo agregar fácilmente una llamada getDatas() en él. La pregunta es cómo "muxear" las llamadas JS en una llamada de back-end, "demuxear" el resultado en las promesas de la persona que llama.

 const cache = Map<number, Promise<Data>>() let requestedIds = [] let timeout = null; // creates just 1 http request (per 100ms)... efficient! function getData(id: number): Promise<Data> { if (cache.has(id)) { return cache; } requestedIds.push(id) if (timeout == null) { timeout = setTimeout(() => { backend.getDatas(requestedIds).then((datas: Data[]) => { // TODO: somehow populate many different promises in cache??? but how? requestedIds = [] timeout = null } }, 100) } return ??? }

En Java, crearía un Map<int, CompletableFuture> y, al finalizar mi solicitud de back-end, buscaría el CompletableFuture y llamaría complete(data) en él. Pero creo que en JS Promise s no se pueden crear sin pasar un resultado explícito.

¿Puedo hacer esto en JS con Promises?

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

No está claro cuál es su objetivo final. Me imagino que podría pasar por sus llamadas según sea necesario; Tal vez algo como:

 for (let x in cache){ if (x.has(id)) return x; } //OR for (let x=0; x<id.length;x++){ getData(id[x]) }

Podría funcionar. Es posible que pueda agregar un método de sincronización a la mezcla si es necesario.

No estoy seguro de en qué consiste su backend, pero sé que GraphQL es un buen sistema para realizar múltiples llamadas.

En última instancia, puede ser mejor manejarlos todos en una sola solicitud, en lugar de múltiples llamadas.

about 4 years ago · Santiago Trujillo Relatório

0

El caché puede ser un identificador de asignación de objeto regular para prometer funciones de resolución y la promesa a la que pertenecen.

 // cache maps ids to { resolve, reject, promise, requested } // resolve and reject belong to the promise, requested is a bool for bookkeeping const cache = {};

Es posible que deba disparar solo una vez, pero aquí sugiero setInterval para verificar regularmente el caché en busca de solicitudes no resueltas:

 // keep the return value, and stop polling with clearInterval() // if you really only need one batch, change setInterval to setTimeout function startGetBatch() { return setInterval(getBatch, 100); }

La lógica empresarial solo llama a getData() que solo entrega (y almacena en caché) promesas, como esta:

 function getData(id) { if (cache[id]) return cache[id].promise; cache[id] = {}; const promise = new Promise((resolve, reject) => { Object.assign(cache[id], { resolve, reject }); }); cache[id].promise = promise; cache[id].requested = false; return cache[id].promise; }

Al guardar la promesa junto con el resolutor y el rechazador, también estamos implementando el caché, ya que la promesa resuelta proporcionará lo que resolvió a través de su método then().

getBatch() le pide al servidor en un lote los ID de getData() aún no solicitados e invoca las funciones de resolución/rechazo correspondientes:

 function getBatch() { // for any const ids = []; Object.keys(cache).forEach(id => { if (!cache[id].requested) { cache[id].requested = true; ids.push(id); } }); return backend.getDatas(ids).then(datas => { Object.keys(datas).forEach(id => { cache[id].resolve(datas[id]); }) }).catch(error => { Object.keys(datas).forEach(id => { cache[id].reject(error); delete cache[id]; // so we can retry }) }) }

El lado de la persona que llama se ve así:

 // start polling const interval = startGetBatch(); // in the business logic getData(5).then(result => console.log('the result of 5 is:', result)); getData(6).then(result => console.log('the result of 6 is:', result)); // sometime later... getData(5).then(result => { // if the promise for an id has resolved, then-ing it still works, resolving again to the -- now cached -- result console.log('the result of 5 is:', result) }); // later, whenever we're done // (no need for this if you change setInterval to setTimeout) clearInterval(interval);
about 4 years ago · Santiago Trujillo Relatório

0

Creo que he encontrado una solución:

 interface PromiseContainer { resolve; reject; } const requests: Map<number, PromiseContainer<Data>> = new Map(); let timeout: number | null = null; function getData(id: number) { const promise = new Promise<Data>((resolve, reject) => requests.set(id, { resolve, reject })) if (timeout == null) { timeout = setTimeout(() => { backend.getDatas([...requests.keys()]).then(datas => { for (let [id, data] of Object.entries(datas)) { requests.get(Number(id)).resolve(data) requests.delete(Number(id)) } }).catch(e => { Object.values(requests).map(promise => promise.reject(e)) }) timeout = null }, 100) } return promise; }

La clave fue descubrir que podía extraer (resolve, reject) de una promesa, almacenarlos, luego recuperarlos y llamarlos más tarde.

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda