1

Tengo una funcion de este tipo:

function pru1(){
    var temp1=pru2('Chocolate');
    if(temp1){
     alert('Chocolate');
    }else{
     alert('Nope');
    }
}

function pru2(element){
    $.get('/listaElementos.php',{
                funcion:'listar',
                element:element
            }).done(function(data){
              return data;
            });
}

el problema es que me evalua temp1 antes de que pru2 conteste, como podria hacer para asegurarme la respuesta de pru2 antes de evaluar con el if?.

Quarkbite
  • 193
  • 2
  • 11
  • Pon el código completo, no sabemos que es `pru2` – Gerardo Oct 23 '17 at 14:27
  • me imagino que pru2 es otra función que controlas, que datos obtienes en es pru2 ? – gama984 Oct 23 '17 at 14:35
  • Bueno a ver, crei que no seria necesario, pru2 evidente que es una funcion que recive como parametro 'Chocolate' y que al ser evaluada por un if devuelve true o false. El problema es que al ser evaluada antes de contestar, temp1 es 'undefined' y por tanto siempre entra en false(alert('nope')), independientemente de lo que pru2 conteste despues. – Quarkbite Oct 23 '17 at 14:40
  • pru2 es una función asícrona? – Pikoh Oct 23 '17 at 14:41
  • 1
    **Añade** el código de la función `pru2`. Es completamente necesaria y relevante porque si fuese síncrona no sucediese lo que comentas. En todo caso, puedes usar callbacks o promesas. – gugadev Oct 23 '17 at 14:45
  • pru2 hace una peticion a una bd, si el elemento existe en la bd devuelve true, si no, false. – Quarkbite Oct 23 '17 at 14:55

2 Answers2

1

No puedes devolver desde un callback hacia el exterior porque es otro scope/ámbito de ejecución. Puedes usar un callback o devolver una promesa.

Callback

function pru2(element, cb){
  $.get('/listaElementos.php',{
    funcion:'listar',
    element:element
  }).done(function(data){
    cb(data);
  });
}

function pru1() {
    pru2('Chocolate', function(temp1) {
      if(temp1){
        alert('Chocolate');
      } else{
       alert('Nope');
      }
    });
}

Promesa

function pru2(element, cb) {
  return new Promise((resolve, reject) => {
    $.get('/listaElementos.php', {
      funcion:'listar',
      element:element
    }).done(function(data) {
      resolve(data);
    }).fail(function(jqxhr, error, status) {
      reject(error);
    });
}

function pru1() {
  pru2('Chocolate')
    .then((temp1) => {
      if(temp1) {
        alert('Chocolate');
      } else {
       alert('Nope');
      }
    })
    .catch(err => console.error(err));
}

// o usando async/await
async function pru1() {
  try {
    const temp1 = await pru2('Chocolate');
    if(temp1){
      alert('Chocolate');
    } else{
      alert('Nope');
    }
  } catch (e) { console.error(e); }
}
gugadev
  • 18,776
  • 1
  • 24
  • 49
0

Lo que pasa es que Javascript va a ejecutar "linealmente" todo lo que pongas en una sola función. A pru1 no le importa (o más bien no sabe) que pru2 va a devolver un valor.

Lo que necesitas hacer es aprender a usar las callbacks que proporciona el lenguaje para hacerlo. El ejemplo más directo lo tienes en el propio $.get donde se esperará a que el servidor responda para ejecutar el camino de done si no hay ningún problema.

En resumidas cuentas, una callback se ejecutará una vez que la función termine. Una aproximación sería:

function pru1(){
  //La función que se pasa como argumento es el callback que se ejecutará al final.
  pru2('Chocolate', function(respuestaCallback){
    if(respuestaCallback){
      alert('Chocolate');
    }else{
      alert('Nope');
    }
  });
}

function pru2(element, callback){
  $.get('/listaElementos.php',{
    funcion:'listar',
    element:element
  }).done(function(data){
    //Una vez que el servidor responda, se invoca a
    //la función pasada como argumento en pru1.
    callback(data);
  });
}
Kroneaux Schneider
  • 3,602
  • 1
  • 8
  • 16
  • Por eso, no entiendo que diferencia hay entre el done del get y un callback. Si la funcion pru2 no responde hasta que el done del get finaliza la consulta, por que se evalua el if en pru1?. Por otro lado, he visto en respuestas de stackoverflow que en jquery existe el $.when() que se supone que hace lo mismo que un callback, no? – Quarkbite Oct 24 '17 at 06:10
  • he intentado usar jquery, de este modo: var dfd = $.Deferred(); dfd.done(pru2('Chocolate')).done(function(n) { console.log(n); }); y de este otro modo: pru2('Chocolate').done(function(a) { console.log(a); }).fail(function() { console.log('error'); }); y no funciona ninguno. – Quarkbite Oct 24 '17 at 07:08