#javascript #jquery #html #web-sql
#javascript #jquery #HTML #web-sql
Вопрос:
Спецификация html5 для ExecuteSQL включает в себя успешный обратный вызов и обратный вызов с ошибкой:
db.transaction(function(tx) {
tx.executeSql('SELECT * FROM MyTable WHERE CategoryField = ?',
[ selectedCategory ],
function (tx, rs) { displayMyResult(rs); },
function (tx, err) { displayMyError(err); } );
});
Если бы я использовал jQuery, есть ли способ реализовать это с использованием нового jQuery promise / deferred hotness?
Ответ №1:
Я просто хотел добавить еще один пример.
(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);
});
})()
Комментарии:
1. Хммм. Я бы подумал, что вы бы вызвали successWrapper (tx, data) вместо successWrapper (d). JavaScript сложен.
2. Проблема, с которой я столкнулся, заключалась в сохранении отложенного объекта в области видимости после вызова ExecuteSQL. Создав функцию, которая возвращает функцию, я достиг этой цели.
Ответ №2:
Наткнулся на этот вопрос, когда искал что-то еще, но я думаю, что у меня есть некоторый шаблонный код, который поможет вам начать обертывание запросов WebSQL в jQuery Promises.
Это пример, sqlProviderBase
для $.extend
использования вашим собственным провайдером. У меня есть пример с taskProvider
и страницей, которая вызывала бы событие taskProvider
on the page show. Это довольно редко, но я надеюсь, что это поможет указать другим правильное направление для обертывания запросов в promise для лучшей обработки.
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: ;-[ ");
});
}
};
Комментарии:
1. Спасибо, Джейкоб! tutsplus.com/lesson/deferreds/?WT.mc_id=learnjquery также говорится об отсрочках. Я смотрю на ваш код, и он соответствует тому, что говорит Джеффри Уэй.
Ответ №3:
Я ждал ответа, но пока ничего, поэтому я попробую. Я не могу запустить это, поэтому приношу извинения за любые ошибки.
Вы ищете что-то вроде:
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); } );
Ответ №4:
Я обнаружил, что обертывание отложенной транзакции в функцию и возврат обещания создает чистую и повторно используемую реализацию шаблона deferred / promise.
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);
});