Foros del Web » Programando para Internet » Javascript »

Problema con ejecución secuencial en Javascript

Estas en el tema de Problema con ejecución secuencial en Javascript en el foro de Javascript en Foros del Web. Hola! Espero que puedan ayudarme porque estoy ya desesperado con este tema.... Se trata de una aplicación que estoy haciendo con NodeJS que como sabrán ...
  #1 (permalink)  
Antiguo 12/04/2017, 05:10
Avatar de fbedia  
Fecha de Ingreso: julio-2010
Mensajes: 159
Antigüedad: 13 años, 9 meses
Puntos: 8
Problema con ejecución secuencial en Javascript

Hola! Espero que puedan ayudarme porque estoy ya desesperado con este tema....

Se trata de una aplicación que estoy haciendo con NodeJS que como sabrán se programa en javascript. Pues bien, el problema es el siguiente:

Se trata de una aplicación donde un usuario crea un juego y otro usuario puede unirse.
El creador y el oponente añaden una serie de "items" que se disputarán.

Cuando un usuario se conecta, lo que quiero hacer es cargar los juegos y mostrarselos.... Lo que hago es:

1º: Una consulta SQL que me devuelva los juegos activos.

2º: Mediante un bucle for, voy recorriendo el resultado de la consulta que contiene los IDs

3º: Dentro del buble for, realizo otra consulta para obtener los items depositados... y a continuacion procedo mediante socket.emit a enviar la informacion.

El problema esta en que el buble for no espera a que se ejecute lo que hay dentro de el! ¿Que puedo hacer? ¿Alguna idea?

El codigo es el siguiente:

Código Javascript:
Ver original
  1. io.on('connection',function(socket) {
  2.     console.log("Nueva conexion al socket");
  3.    
  4.     //SQL para obtener la informacion de los juegos:
  5.     db_connection.query('SELECT juegos.id, juegos.creador, usuarios.avatar, usuarios.realname FROM juegos, usuarios WHERE juegos.creador=usuarios.steamid ORDER BY finalizado ASC, fecha_fin DESC LIMIT 0,100', function(error1,juegos){
  6.         if(error1) {
  7.             log.error("No pueden obtenerse los datos de los juegos!");
  8.             console.log("ERROR -> "+error1);
  9.             return;
  10.         } else {
  11.             if(!juegos[0]) {
  12.                 //Si no existen juegos emito un succes false
  13.                 socket.emit('juegos',{success: false});
  14.             } else {
  15.                 //Mediante un bucle for recorro los juegos
  16.                 for (var i in juegos) {
  17.                     console.log("Bucle for entra en su ejecucion numero "+i+". El ID del juego es "+juegos[i].id);
  18.                     //Cargo los items del juego
  19.                     db_connection.query('SELECT market_hash_name,icon,value,del_creador FROM juegos_items WHERE id_juego='+juegos[i].id, function(error3,items){
  20.                         if((error3)||(!items[0])) {
  21.                             log.error("Error en la carga de Items de un duelo");
  22.                         } else {
  23.                             console.log("Cargando los items del juego con ID:"+juegos[i].id);
  24.                             //Avatar del oponente:
  25.                             db_connection.query('SELECT realname, avatar FROM usuarios WHERE steamid='+juegos[i].oponente, function(error2,oponente){
  26.                                 if((error2)||(!oponente[0])) {
  27.                                     console.log("Emito los datos del Id juego "+juegos[i].id);
  28.                                     socket.emit('juegos',{
  29.                                         success: true,
  30.                                         gameId: juegos[i].id,
  31.                                         creador: juegos[i].creador,
  32.                                         creador_avatar: juegos[i].avatar,
  33.                                         creador_nick: juegos[i].realname,
  34.                                         oponente: null,
  35.                                         oponente_avatar: null,
  36.                                         oponente_nick: null,
  37.                                         items: items
  38.                                     });
  39.                                 } else {
  40.                                     socket.emit('juegos',{
  41.                                         success: true,
  42.                                         gameId: juegos[i].id,
  43.                                         creador: juegos[i].creador,
  44.                                         creador_avatar: juegos[i].avatar,
  45.                                         creador_nick: juegos[i].realname,
  46.                                         oponente: juegos[i].oponente,
  47.                                         oponente_avatar: oponente[0].avatar,
  48.                                         oponente_nick: oponente[0].realname,
  49.                                         items_creador: items
  50.                                     });
  51.                                 }
  52.                             });
  53.                         }
  54.                     });
  55.                 }
  56.             }
  57.         }
  58.     });
  59.    
  60. });

Mirad el log:



Bucle for entra en su ejecucion numero 0. El ID del juego es 1
Bucle for entra en su ejecucion numero 1. El ID del juego es 2
Cargando los items del juego con ID:2
Cargando los items del juego con ID:2
Emito los datos del Id juego 2
Emito los datos del Id juego 2


Quiero que el codigo se ejecute secuencialmente... El log deberia mostrar algo asi:

Bucle for entra en su ejecucion numero 0. El ID del juego es 1
Cargando los items del juego con ID:1
Emito los datos del Id juego 1
Bucle for entra en su ejecucion numero 1. El ID del juego es 2
Cargando los items del juego con ID:2
Emito los datos del Id juego 2


Espero haberme explicado bien!
Cualquier duda muy gustosamente tratare de aclararla.

Muchas gracias por vuestro tiempo
__________________
Follow me on twitter @franbedia
  #2 (permalink)  
Antiguo 12/04/2017, 08:50
 
Fecha de Ingreso: septiembre-2012
Ubicación: Pontevedra
Mensajes: 48
Antigüedad: 11 años, 7 meses
Puntos: 2
Respuesta: Problema con ejecución secuencial en Javascript

Sinceramente, nunca he trabajado con esas librerias así que hablo un poco sin saber, pero te comento un problema similar que tenia yo en Ajax.

Yo utilizaba una llamada ajax a otro archivo, para recuperar un valor de la base de datos, que después utilizaba en el resto del código javascript.
Me fallaba por ajax se ejecutaba más lento que el código javascript, por lo tanto cuando llamaba a ajax, se seguía ejecutando el resto del código antes de que ajax, devolviera el valor que necesitaba.

Por lo tanto es posible que tu problema sea similar que el bucle for continua cuando aun estas ejecutando la función anterior.

Un saludo!
  #3 (permalink)  
Antiguo 12/04/2017, 09:17
Avatar de fbedia  
Fecha de Ingreso: julio-2010
Mensajes: 159
Antigüedad: 13 años, 9 meses
Puntos: 8
Respuesta: Problema con ejecución secuencial en Javascript

Cita:
Iniciado por barbel Ver Mensaje
Sinceramente, nunca he trabajado con esas librerias así que hablo un poco sin saber, pero te comento un problema similar que tenia yo en Ajax.

Yo utilizaba una llamada ajax a otro archivo, para recuperar un valor de la base de datos, que después utilizaba en el resto del código javascript.
Me fallaba por ajax se ejecutaba más lento que el código javascript, por lo tanto cuando llamaba a ajax, se seguía ejecutando el resto del código antes de que ajax, devolviera el valor que necesitaba.

Por lo tanto es posible que tu problema sea similar que el bucle for continua cuando aun estas ejecutando la función anterior.

Un saludo!
Si, en esencia el problema es el mismo.

Gracias por interesarte.
__________________
Follow me on twitter @franbedia
  #4 (permalink)  
Antiguo 16/04/2017, 15:08
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: Problema con ejecución secuencial en Javascript

Buenas,

yo también desconozco esas librerías pero ya que usas node, usa promesas para evitar que tu codigo parezca esto:


Por ejemplo:

Código Javascript:
Ver original
  1. function obtenerItems() {
  2.     return new Promise((resolve, reject) => {
  3.         db_connection.query('mi query', (error, items) => {
  4.              if (errors) {
  5.                   reject(new Error('error 1'))
  6.              } else {
  7.                   resolve(items)
  8.              }
  9.         })
  10.     })
  11. }
  12.  
  13. function hacerAlgoConLosItems(items) {
  14.     return new Promise((resolve, reject) => {
  15.         db_connection.query('query que hace algo con ' + items, (error) => {
  16.              if (errors) {
  17.                   reject(new Error('error 2'))
  18.              } else {
  19.                   resolve()
  20.              }
  21.         })
  22.     })
  23. }
  24.  
  25. // y luego hacer algo así para qu se ejecute una detrás de la otra.
  26. obtenerItems()
  27.     .then(hacerAlgoConLosItems)
  28.     .catch((error) => {
  29.          console.log(error.message) // mostrar el error si se ha producido
  30.     })

Un saludo!
__________________
github.com/xgbuils | npm/xgbuils
  #5 (permalink)  
Antiguo 18/04/2017, 03:25
Avatar de manuparquegiralda  
Fecha de Ingreso: junio-2012
Ubicación: Barcelona
Mensajes: 241
Antigüedad: 11 años, 9 meses
Puntos: 39
Respuesta: Problema con ejecución secuencial en Javascript

Verás tienes que hacer algo más recursivo, no debes hacerlo con un bucle for ya que el bucle te recorrerá todos los valores de los juegos sin esperar a que el resultado de cada juego sea devuelto.

Deberías buscar el resultado de un juego y cuando lo obtengas, entonces buscar el resultado del siguiente y así mientras haya juegos. No sé si me he explicado bien. Te pondré algo a modo de ejemplo simple para que lo veas:

Código Javascript:
Ver original
  1. if(!juegos[0]) {
  2.     //Si no existen juegos emito un succes false
  3.     socket.emit('juegos',{success: false});
  4. } else {
  5.     //Mediante un bucle for recorro los juegos
  6.  
  7.     //Cargo los items del primer juego, ( el cero es el primer index del array)
  8.     cargarDatosJuego( juegos, 0 );
  9. }
  10.  
  11. function cargarDatosJuego( juegos, i ) {
  12.     if ( !juegos[ i ] ) {
  13.         console.log("No hay más juegos por cargar");
  14.         return false;
  15.     }
  16.  
  17.     db_connection.query('SELECT market_hash_name,icon,value,del_creador FROM juegos_items WHERE id_juego='+juegos[i].id, function(error3,items){
  18.         if((error3)||(!items[0])) {
  19.             log.error("Error en la carga de Items de un duelo");
  20.  
  21.             cargarDatosJuego( juegos, i++ ); // Volvemos a llamar a la función sumando uno al index para cargar el siguiente juego
  22.  
  23.         } else {
  24.             console.log("Cargando los items del juego con ID:"+juegos[i].id);
  25.             //Avatar del oponente:
  26.             db_connection.query('SELECT realname, avatar FROM usuarios WHERE steamid='+juegos[i].oponente, function(error2,oponente){
  27.                 if((error2)||(!oponente[0])) {
  28.                     console.log("Emito los datos del Id juego "+juegos[i].id);
  29.                     socket.emit('juegos',{
  30.                         success: true,
  31.                         gameId: juegos[i].id,
  32.                         creador: juegos[i].creador,
  33.                         creador_avatar: juegos[i].avatar,
  34.                         creador_nick: juegos[i].realname,
  35.                         oponente: null,
  36.                         oponente_avatar: null,
  37.                         oponente_nick: null,
  38.                         items: items
  39.                     });
  40.                 } else {
  41.                     socket.emit('juegos',{
  42.                         success: true,
  43.                         gameId: juegos[i].id,
  44.                         creador: juegos[i].creador,
  45.                         creador_avatar: juegos[i].avatar,
  46.                         creador_nick: juegos[i].realname,
  47.                         oponente: juegos[i].oponente,
  48.                         oponente_avatar: oponente[0].avatar,
  49.                         oponente_nick: oponente[0].realname,
  50.                         items_creador: items
  51.                     });
  52.                 }
  53.  
  54.                 cargarDatosJuego( juegos, i++ ); // Volvemos a llamar a la función sumando uno al index para cargar el siguiente juego
  55.  
  56.             }
  57.         }
  58.     }
  59. }

Obviamente es mucho más optimizable, pero esta es la idea, no sé si estará bien escrito o habrá errores, pero bueno eso ya lo miras tu. El caso es que tienes que llamar a la función dentro de la función una y otra vez mientras haya juegos por cargar y cuando no hay más juegos, la detienes.

Es un códifo un tanto lioso y no me he parado a estudiar si hay variables compartidas que también tendrían que estar en la función y demás detalles. No copies y pegues, lo único que intento es pasarte una idea de como hacerlo.
__________________
Diseño Web - Arisman Web

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:15.