¿Cómo puedo establecer una variable local en Javascript en una función que utilicé como parámetro?

Tengo un problema con Javascript al usar Barcodescannerplugin para Phonegap en una aplicación de Android.

El complemento que uso trae un pequeño Javascript para habilitar el uso de Barcodescanner en mi aplicación Phongap. Pero en mi opinión, la interfaz de las funciones javascript provistas no es tan óptima, porque no quiero hacer un manejo de errores en cada posición donde uso estos métodos.

Es por eso que traté de hacer esa interfaz más fácil en el camino, solo tengo que llamar a un método scanBarcode() y el script de llamada obtiene el texto del escaneo o nada, si algo falla. Aquí está el código:

function scanBarcode(){
    var resultText = '';
    window.plugins.barcodeScanner.scan( 
        function(result) {
            if (!result.cancelled){
                resultText = result.text;
            }
        },
        function(error) {
            alert("Scanning failed: " + error);
        }
    );
    return resultText;
}

El complemento que uso se puede encontrar en: Github Phonegap Complementos Android/BarcodeScanner

El resultado de mi Método es siempre el mismo, una cadena vacía. Creo que la razón es el alcance variable, pero no estoy seguro de cómo resolver el problema.

preguntado el 25 de agosto de 12 a las 11:08

2 Respuestas

La razón es porque el window.plugins.barcodeScanner.scan El método se ejecuta de forma asincrónica: la devolución de llamada exitosa no se llama hasta que el método ha regresado.

Recomiendo devolver un Promise objeto de su método, así que algo como (usando jQuery como ejemplo):

var result = $.Deferred();
window.plugins.barcodeScanner.scan( 
    function(result) {
        if (!result.cancelled){
            result.resolve(result.text);
        }
    },
    function(error) {
        result.reject(error);
    }
);

return result;

Respondido 25 ago 12, 11:08

OK, entonces, ¿no hay alguna forma de hacer que esta interfaz sea más fácil de la forma en que lo probé? - Marco Berndt

Ah, está bien, gracias, probaré este ejemplo porque también estamos usando jQuery Mobile en esta aplicación web. - Marco Berndt

Hola Rich, he usado tu código de ejemplo y jQuery Mobile ahora. El resultado es que recupero un objeto, pero no puedo sacar la cadena escaneada. O de lo contrario, ¿no entendí bien la documentación de la API si pensé que el parámetro dado al método de resolución del objeto diferido es el valor que se devuelve a todos los métodos de devolución de llamada? Intenté algo así: function clickScanBarcode(){ var result = scanBarcode(); alerta (resultado); } - Marco Berndt

@Marcus: No, el valor que se devuelve is el objeto diferido. Debe registrar las devoluciones de llamada en ese objeto, que se ejecutan cuando se resuelve el objeto diferido. api.jquery.com/category/objeto-diferido - Félix Kling

Gracias por tu ayuda, ahora funciona :)

Para todos los demás que también tienen este problema, la resolución se ve así:

function scanBarcode(){
    var resultObject = $.Deferred();
    window.plugins.barcodeScanner.scan(
        function(result) {
            if (!result.cancelled){
                resultObject.resolve(result.text);
            } else {
                resultObject.resolve('');
            }
        },
        function(error) {
            resultObject.resolve('');
        }
    );
    return resultObject;
}

Y ahora es fácil obtener el valor escaneado simplemente diciendo que:

function clickScanBarcode(){
    var result = scanBarcode();
    result.done( function(text){
        alert('Barcodetext:'+text);
    });
}

Cambié el código por error y lo cancelé en la forma en que siempre obtengo una cadena vacía para manejar. Más manejo de errores no es útil en mi caso.

Saludos, marcus

Respondido 26 ago 12, 09:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.