2011-11-08 8 views
6

La especificación jQuery diferido/html5 para ExecuteSQL incluye una devolución de llamada de éxito y una falla de devolución de llamada:envolver WebSQL ExecuteSQL llama en una promesa

db.transaction(function(tx) {  
    tx.executeSql('SELECT * FROM MyTable WHERE CategoryField = ?', 
    [ selectedCategory ], 
    function (tx, rs) { displayMyResult(rs); }, 
    function (tx, err) { displayMyError(err); }); 
}); 

Si estuviera usando jQuery, ¿hay una forma de implementar esto usando la nueva jQuery promesa/calor diferido?

Respuesta

2

He estado esperando una respuesta, pero nada tan lejos, así que voy a tomar una foto. No puedo ejecutar esto, así que me disculpo por cualquier error.

¿Estás buscando algo como:

function deferredTransaction(db,transaction,transactionFunction(transaction)) { 
    me=this; 
    return $.Deferred(function(deferedObject){ 
     db.transaction(transactionFunction(transaction), 
     function(tx,rs) { me.resolve(tx,rs); }, 
     function(tx,err) { me.reject(tx,err); }); 
    }).promise(); 
} 

dtx=deferredTransaction(db,tx,function(tx) {  
    tx.executeSql('SELECT * FROM MyTable WHERE CategoryField = ?', 
    [ selectedCategory ]); 
dtx.then(function (tx, rs) { displayMyResult(rs); }, 
    function (tx, err) { displayMyError(err); }); 
3

Tropezamos con esta pregunta mientras se busca otra cosa, pero creo que tengo algo de código de plantilla que le ayudará a empezar envolviendo consultas WebSQL en promesas jQuery.

Este es un ejemplo sqlProviderBase a $.extend en su propio proveedor. Tengo un ejemplo con un taskProvider y una página que llamaría al taskProvider en el evento de mostrar página. Es bastante escaso, pero espero que ayude a orientar a los demás en la dirección correcta para envolver las consultas en una promesa de un mejor manejo.

var sqlProviderBase = { 

    _executeSql: function (sql, parms) { 

     parms = parms || []; 

     var def = new $.Deferred(); 

     // TODO: Write your own getDb(), see http://www.html5rocks.com/en/tutorials/webdatabase/todo/ 
     var db = getDb(); 

     db.transaction(function (tx) { 
      tx.executeSql(sql, parms, 
      // On Success 
      function (itx, results) { 
       // Resolve with the results and the transaction. 
       def.resolve(results, itx); 
      }, 
      // On Error 
      function (etx, err) { 
       // Reject with the error and the transaction. 
       def.reject(err, etx); 
      }); 
     }); 

     return def.promise(); 
    } 
}; 

var taskProvider = $.extend({}, sqlProviderBase, { 

    getAllTasks: function() { 

     return this._executeQuery("select * from Tasks"); 

    } 

}); 

var pageThatGetsTasks = { 
    show: function() { 

     taskProvider.getAllTasks() 
        .then(function(tasksResult) { 

         for(var i = 0; i < tasksResult.rows.length; i++) { 
          var task = tasksResult.rows.item(i); 

          // TODO: Do some crazy stuff with the task... 
          renderTask(task.Id, task.Description, task.IsComplete); 

         } 

        }, function(err, etx) { 

         alert("Show me your error'd face: ;-[ "); 

        }); 

    } 
}; 
+0

Gracias Jacob! http://tutsplus.com/lesson/deferreds/?WT.mc_id=learnjquery también habla de deferreds. Estoy viendo tu código y está en línea con lo que Jeffrey Way dice que haga. –

7

Solo quería añadir un ejemplo más.

(function() { 
    // size the database to 3mb. 
    var dbSize = 3 * 1024 * 1024, 
     myDb = window.openDatabase('myDb', '1.0', 'My Database', dbSize); 

    function runQuery() { 
     return $.Deferred(function (d) { 
      myDb.transaction(function (tx) { 
       tx.executeSql("select ? as Name", ['Josh'], 
       successWrapper(d), failureWrapper(d)); 
      }); 
     }); 
    }; 

    function successWrapper(d) { 
     return (function (tx, data) { 
      d.resolve(data) 
     }) 
    }; 

    function failureWrapper(d) { 
     return (function (tx, error) { 
      d.reject(error) 
     }) 
    }; 

    $.when(runQuery()).done(function (dta) { 
     alert('Hello ' + dta.rows.item(0).Name + '!'); 
    }).fail(function (err) { 
     alert('An error has occured.'); 
     console.log(err); 
    }); 

})() 
+0

Hmmm. Creo que llamarías a successWrapper (tx, data) en lugar de successWrapper (d). JavaScript es difícil. –

+0

El desafío al que me había enfrentado era mantener el objeto diferido en el alcance, después de llamar a executeSql. Al crear una función que devuelve una función, logré ese objetivo. – JoshRoss

2

me parece que si se envuelve la transacción diferida en una función y devolver la promesa crea un aspecto y reutilizable aplicación limpia del patrón/promesa diferido.

var selectCategory = function() { 
    var $d = $.Deferred(); 

    db.transaction(
     function(tx) { 
      tx.executeSql(
       "SELECT * FROM MyTable WHERE CategoryField = ?" 
       , [selectedCategory] 
       , success 
       , error 
      ) 
     } 
    ); 

    function success(tx, rs) { 
     $d.resolve(rs); 
    } 

    function error(tx, error) { 
     $d.reject(error); 
    } 

    return $d.promise(); 
}; 

selectCategory() 
    .done(function(rs){ 
     displayMyResult(rs); 
    }) 
    .fail(function(err){ 
     displayMyError(err); 
    }); 
Cuestiones relacionadas