Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

javascript - HTML5 Web SQL Transactions skipped without error when touch triggered in IOS

I'm experiencing problems making database transactions on IOS devices. If the user doesn't touch the phone, everything works like expected. If the user taps/scrolls/touches the screen, some transactions directly call their successCallback, without ever calling the actual transaction callback.

Simplified example here: http://jsfiddle.net/Tk9rv/

To test, just open http://jsfiddle.net/Tk9rv/embedded/result/ in your mobile safari on IOS and do not touch the device while loading. You will see a list of debug messages being generated looking like this:

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'
[...]

Now, reload the page and while loading, scroll and tap randomly. You will see some "about to insert..." messages are missing.

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'
[...]

This is because the transactionCallback is completely skipped! But WHY? And WHY does the successCallback fire instead of the errorCallback?

[This is a simplified example, please do not tell me not to do this setTimeout stuff. In the real world, there is data being loaded async and then being inserted... :) ]

I think there is a similar problem here HTML5 Web SQL transaction Missing In Action but there is no solution or hint either.

Any ideas? I'm stuck... Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Our testing showed that this behaviour would also occur whenever the keyboard was displaying and would prevent transactions in an onblur or onfocus event (although, not onkey{down|up|press}). Using setTimeout would cause terrible performance issues. We had found that the .transaction() success callback would be triggered, even if the transaction callback was not called, so came up with this method that works well for us:

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;
}

This code checks that the transaction callback has fired in the success handler and, if not, gives it another chance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...