2012-07-02 9 views
7

De acuerdo ... a las 2 a.m., aquí es donde trazo la línea. Ayuda ... antes de que mi laptop termine saliendo por la ventana. :)Espere a AJAX antes de continuar a través de la función separada

He intentado usar setTimer, devoluciones de llamada, y todo lo demás que puedo pensar (junto con algunas otras sugerencias de Stackoverflow por supuesto). He eliminado todo, así que dejo solo el código base.

Lo que estoy buscando hacer es llamar a parseRow() y antes de guardar el registro al final, necesito obtener la categoría asociada (a través de AJAX); sin embargo, pasa justo al lado, así que la categoría siempre está "indefinida".

function parseRow(row){ 
    var rowArray  = row.trim().split(","); 
    var date   = rowArray[0]; 
    var checknum  = rowArray[1]; 
    var payee  = rowArray[2]; 
    var memo   = rowArray[3]; 
    var amount  = rowArray[4]; 

    //ERROR: blows right past this one and sets the category variable BEFORE ajax returns 
    var category = autoSelectCategory(payee); 

    saveRecord(date, checkNum, payee, memo, category, payment, deposit); 
} 

function autoSelectCategory(payee) { 
    var data; 
    $.ajax({ 
     async: false, 
     url: "autoselectcategory", 
     dataType: "json", 
     data: { 
      string: payee 
     }, 
     success: function (returnedData) { 
      data = returnedData; 
     } 
    }); 
    return data; 
} 
+0

EDIT: @ agregó la sugerencia de extravagante que hizo en respuesta a penartur a responder desde que era un idiota y no regresó los datos correctamente - que es lo que me pasa por quedarse hasta muy tarde. Lo anterior en realidad hace el truco ahora. Sin embargo, voy a implementar la devolución de llamada. – glassfish

Respuesta

12

AJAX representa asíncrona. Eso significa que en su código original, saveRecord se ejecutará antes de el cliente recibirá la respuesta del servidor (y, dependiendo de la implementación $.ajax, podría ser antes de que el cliente envíe la solicitud al servidor).

Además, parece que no entiende cómo funcionan las funciones en JS. var category = autoSelectCategory(payee); establecerá la categoría al valor de retorno de autoSelectCategory; pero la función autoSelectCategory en su código no devuelve nada.

Desde el otro lado, el valor data devolución de su función anónima sólo podía ser utilizado por $.ajax función (y $.ajax probable que ignora el valor de retorno success parámetro).

Este es el código que debería funcionar:

function parseRow(row){ 
    var rowArray  = row.trim().split(","); 
    var date   = rowArray[0]; 
    var checknum  = rowArray[1]; 
    var payee  = rowArray[2]; 
    var memo   = rowArray[3]; 
    var amount  = rowArray[4]; 

    autoSelectCategory(payee, function (category) {  
     saveRecord(date, checkNum, payee, memo, category, payment, deposit); 
    }); 
} 

function autoSelectCategory(payee, callback) { 
    $.ajax({ 
     async: false, 
     url: "autoselectcategory", 
     dataType: "json", 
     data: { 
      string: payee 
     }, 
     success: callback 
    }); 
} 
+1

Dado que está usando 'async: false', entonces' saveRecord' ** no se ejecutará ** antes de que '$ .ajax' termine el trabajo. He * es * devolviendo el valor incorrectamente sin embargo. Definir 'var data;' antes de '$ .ajax', configurarlo en' success' y regresar después de '$ .ajax' debería funcionar. Sin embargo, es una práctica ** realmente mala ** usar 'async: false'. – freakish

+0

@freakish Debería haber notado el 'async: false'. Ni siquiera sabía que era posible :) – penartur

+0

¡Gracias a los dos! ¡Exactamente lo que estaba buscando! – glassfish

9

no utilice async: false opción. Es un mal puro (bloquea todos los scripts en el navegador e incluso en otras pestañas!) Y está en desuso desde jQuery 1.8. Deberías usar devoluciones de llamada como siempre debería ser.

function parseRow(row) { 
    /* the other code */ 
    autoSelectCategory(payee, function() { 
     saveRecord(date, checkNum, payee, memo, category, payment, deposit); 
    }); 
} 

function autoSelectCategory(payee, callback) { // <---- note the additional arg 
    $.ajax({ 
     url: "autoselectcategory", 
     dataType: "json", 
     data: { 
      string: payee 
     }, 
     success: function(res) { 
      /* the other code */ 
      callback(); 
     } 
    }); 
} 
Cuestiones relacionadas