HTML5 Web SQL Транзакции пропускаются без ошибок при срабатывании касания в IOS - PullRequest
11 голосов
/ 05 января 2012

У меня проблемы с выполнением транзакций базы данных на устройствах IOS.Если пользователь не трогает телефон, все работает как ожидалось.Если пользователь нажимает / прокручивает / касается экрана, некоторые транзакции напрямую вызывают свой successCallback, даже не вызывая реальный обратный вызов транзакции.

Упрощенный пример здесь: http://jsfiddle.net/Tk9rv/

Чтобы проверить, просто откройтеhttp://jsfiddle.net/Tk9rv/embedded/result/ в вашем мобильном сафари на IOS и не трогайте устройство во время загрузки.Вы увидите список генерируемых отладочных сообщений, выглядящий следующим образом:

database is running
table will be cleared
store method called for '10'.
about to insert '10'.
transaction successful for '10'
store method called for '9'.
about to insert '9'.
transaction successful for '9'
store method called for '8'.
about to insert '8'.
transaction successful for '8'
[...]

Теперь перезагрузите страницу и во время загрузки прокрутите и коснитесь случайным образом.Вы увидите, что некоторые сообщения «о том, чтобы вставить ...» отсутствуют.

database is running
table will be cleared
store method called for '10'.
about to insert '10'.
transaction successful for '10'
store method called for '9'.
about to insert '9'.
transaction successful for '9'
store method called for '8'.
transaction successful for '8' <-- WHERE IS MY "about to insert '8'." ???
store method called for '7'.
about to insert '7'.
transaction successful for '7'
[...]

Это потому, что транзакция CallCallback полностью пропущена!Но почему?И ПОЧЕМУ срабатывает successCallback вместо errorCallback?

[Это упрощенный пример, пожалуйста, не говорите мне не делать этот набор setTimeout.В реальном мире данные загружаются асинхронно, а затем вставляются ... :)]

Я думаю, что здесь есть похожая проблема Транзакция HTML5 Web SQL отсутствует в действии , но естьнет ни решения, ни намека.

Есть идеи?Я застрял ... Спасибо!

Ответы [ 2 ]

9 голосов
/ 13 апреля 2012

Наше тестирование показало, что такое поведение также будет происходить всякий раз, когда клавиатура отображалась, и будет предотвращать транзакции в событии onblur или onfocus (хотя не onkey {down | up | press}). Использование setTimeout может привести к ужасным проблемам с производительностью. Мы обнаружили, что обратный вызов .transaction () будет запущен, даже если обратный вызов транзакции не был вызван, поэтому мы нашли этот метод, который хорошо работает для нас:

var oldOpenDatabase = window.openDatabase;
window.openDatabase = function() {
    var db = oldOpenDatabase.apply(window, arguments);

    var oldTrans = db.transaction;
    db.transaction = function(callback, err, suc) {
        var db = this;
        var params = arguments;
        var hasRun = false;
        oldTrans.call(db, function(tx){
            hasRun = true; callback(tx);
        }, err||function(){}, function(tx) {
            if(hasRun){
                if (suc != undefined)
                    suc(tx); 
                return;
            }
            else {
                oldTrans.apply(db, params);
            }
        });
    }

    return db;
}

Этот код проверяет, что обратный вызов транзакции сработал в обработчике успеха, и, если нет, дает ему еще один шанс.

0 голосов
/ 19 марта 2012

Web Workers и OpenDatabaseSync решают ту же проблему на моем сайте. За исключением того, что веб-работники не поддерживаются на iOS4.x и Android, поэтому мы можем реализовать старый способ для тех и веб-работников на iOS5.

В простейшем примере, приведенном ниже, используется цикл для 500 раз записи одной вставки на экран после каждой вставки. В конце делается запрос, чтобы вернуть количество строк в таблице. Теперь мы видим, что транзакции не пропущены даже при большой прокрутке.

Этот пример разработан таким образом, чтобы вы могли проверить устойчивость к прокрутке во время вставок на iPhone или iPad.

Требуются две страницы, html-страница и отдельный файл javascript для работника. Так что для HTML-страницы;

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <title></title>
    <script src="../scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
    <style type="text/css">
    body
    {
    background-color:Black;
    }
    .number
    {
    color:#00FF00;
    font-family:Courier New;
    font-size:12pt;
    }
    button
    {
    position:fixed;
    right:5px;
    top:5px;
    padding:15px;
    }
    </style>
    <script type="text/javascript">
    var worker;
    $(document).ready(function () {

        worker = new Worker('worker1.js');
        worker.addEventListener('message', function (e) {
        $("#test").html(new Date().toLocaleTimeString() + " " + e.data.message + "<BR/>" + $("#test").html());
        if (e.data.complete == true) {
            worker.terminate();
        }
        }, false);
    });

    function stop() {
        worker.terminate();
    }
    </script>

</head>
<body>
    <form id="form1" onsubmit="return false">
    <div id="test" class="number">
    <button onclick="stop()">Stop</button>
    </div>
    </form>
</body>
</html>

и worker1.js;

var wdb = {};
wdb.db = openDatabaseSync('test', '1.0', 'DB test', 1024);

doQuery("CREATE TABLE IF NOT EXISTS test(abc INTEGER PRIMARY KEY);");
doQuery("DELETE FROM test"); // optional

for (var i = 0; i < 500; i++) {
    doQuery("INSERT INTO test(abc) VALUES( " + i + " );");
    postMessage({ message: "Inserted " + i.toString(), complete: false });
}

var summary= doQuery("SELECT COUNT(*) AS Total FROM test;");
postMessage({ message: "Found " + summary.item(0).Total.toString() + " rows", complete: true });

function doQuery(sql) {
    wdb.db.transaction(function (tx) {
    rs = tx.executeSql(sql, []);
    });
    return rs.rows;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...