NILGroup / TFG-1920-Text2LSE

Trabajo Fin de Grado UCM (TextToLSE)
0 stars 1 forks source link

Problema sincronización fetch #123

Open AlejandroTorralboFuentes opened 4 years ago

AlejandroTorralboFuentes commented 4 years ago

Hola Antonio,

Tenemos un pequeño problema con el fetch de las imágenes. Primero, hacemos una llamada fetch al texto, y posteriormente mediante un bucle hacemos las llamadas fetch para hacer GET de las imágenes. El texto está perfecto, pero el problema es que tras hacer las llamadas GET las imágenes llegan desordenadas, y no encontramos la manera de que lleguen en orden.

El código está subido a la rama Web-Fetch-Imagenes, en el fichero scrips.js, función GetImageSentence, que a su vez llama a getImages.

Hemos probado utilizando la instruccion await, pero no da resultado. Porfi, ¿podrías echarnos un cable?

Muchas gracias!

agarsev commented 4 years ago

El problema es aquí? (si pincháis en la línea en el código en github os permite sacar un enlace).

En javascript moderno se tiende a utilizar un estilo de programación más funcional, en lugar de bucles for usamos la función map. Así, cada palabra la "mapeamos" a un fetch, y tenemos un array de fetchs. Pero como cada promesa (el resultado de fetch) puede resolverse en un orden distinto, tenemos la función Promise.all que manda varias promesas (fetches) a la vez, espera a todas, y devuelve los resultados en el orden que se le han pedido.

En caso de querer hacerlo estilo "síncrono", con await, esto sólo se puede hacer dentro de funciones de tipo async, así que tendríais que convertir vuestra función en async.


Es decir, hay las siguientes opciones:

Promise.all(array_de_palabras.map(palabra => fetch(`/url/blablabla/${palabra}`)))
    .then(array_de_imagenes_en_orden => {
        // hacer lo que sea
    });

ó

async function getImagenesparaFrase (palabras) {
    let imagenes = [];
    for (palabra of palabras) {
        imagenes.push(await fetch(`/url/blablabla/${palabra}`));
    }
    return ret;
}
getImagenesparaFrase(palabras).then(imagenes => {
     // hacer lo que sea
})

He escrito ese código aquí directamente sin probarlo, pero es javacript real, y así aprovecho también y os enseño algunas cosas de javascript moderno (estilo funcional, promesas, let, arrow functions, template strings) que os recomiendo que uséis en el futuro o que incluso podéis empezar a usar ya. El javascript moderno es mucho más elegante y cómodo de escribir, y hace innecesario jQuery con lo que las aplicaciones son más ligeras y van mucho más rápido.

svegascanas commented 4 years ago

Hola Antonio,

Muchas gracias por la rapidez en tu respuesta. Hemos probado las dos opciones que comentas, pero nos siguen apareciendo las imágenes desordenadas, a pesar de que el texto nos lo devuelve perfecto.

Hemos subido a la misma rama el nuevo archivo scripts.js, que contiene las tres versiones: la antigua con el for y las dos nuevas que nos propones. Ninguna nos respeta el orden de las imágenes.

Le hemos dado mil vueltas y no conseguimos dar con la solución.

Un saludo y muchas gracias.

agarsev commented 4 years ago

Poned enlaces a las líneas de código si tenéis problemas concretos para no tener que andar buscando.

En https://github.com/NILGroup/TFG-1920-Text2LSE/blob/16997c2a87c232d9c4d1411dce1b37e727e84d3e/Web/scripts.js#L196 las responses deberían estar en orden, habéis probado a mirarlas con un console.log? Me parece que la línea en la que estáis perdiendo el orden es https://github.com/NILGroup/TFG-1920-Text2LSE/blob/16997c2a87c232d9c4d1411dce1b37e727e84d3e/Web/scripts.js#L207 donde estáis usando de nuevo promesas y por tanto no se garantiza el orden.

En cualquier caso, no veo por qué hacéis fetch para las imágenes. Una vez tenéis las palabras, la url de la imagen ya la sabéis, por qué no ponerle esa url directamente al src de un elemento img y que sea el navegador el que las carga?

A veces es bueno vaciar el cerebro, descansar unos días y luego volver fresco al problema. También es muy recomendable refactorizar y reescribir a menudo. Si le das mil vueltas a una cosa y no se soluciona, probablemente es que hay que hacer garbage collect de la cabeza.