# Auf Funktion warten



## Fruitgum (6. Januar 2012)

Hallo,

Asynchrone an JS macht mir ein bisschen zu schaffen

Ich will nun meine Database SQLite erstmal Initialisieren und erst dann soll es weitergehen.

Leider geht das irgendwie zu langsam und eine andere funktion will dann schon in die Database schreiben, obwohl sie ja nun noch gar net fertig ist.

Bisschen Code:

```
function initfunc() {
          initDB();
          checkAllDBs();
}

function onLoad() {
          document.addEventListener("deviceready", onDeviceReady, false);
          
}

function onDeviceReady() {
         initfunc();

         // ab hier soll es erst weiter gehen wenn wenn initfunc() fertig ist.
}
```


Und was ist der Unterschied zwischen solch einer Funktion:

function blablupp() {

}


und dieser:


blablupp = function() {


}


LG


----------



## CPoly (6. Januar 2012)

Du musst eben so was in der Art machen:


```
function initfunc(fn) {
    initDB(function() {
        checkAllDBs(function() {
            fn();
        });
    });
}
 
function onLoad() {
          document.addEventListener("deviceready", onDeviceReady, false);
}
 
function onDeviceReady() {
    initfunc(function() {
         // ab hier soll es erst weiter gehen wenn wenn initfunc() fertig ist.
    });
}
```




Fruitgum hat gesagt.:


> Und was ist der Unterschied zwischen solch einer Funktion:
> 
> function blablupp() {
> 
> ...




Im Prinzip keiner.


----------



## Fruitgum (6. Januar 2012)

mmm so richtig will das nicht. ich habs so:


```
function initfunc(fn) {
          initDB(function() {
          
                    checkAllDBs(function() {
                    
                          fn();       
                    
                    });
         
          });
}

function onLoad() {
          
          document.addEventListener("deviceready", onDeviceReady, false);
          
}

function onDeviceReady() {
         
          initfunc(function() {
                    console.log('im onReady');
          });
}
```

in der Konsole wird mir _im onReady _ schon ausgegeben, danach kommt checkAllDBs() seine Ausgabe.


ich gehe in initDB() öffne die Datenbank,
dann muss er in checkAllDBs() kucken ob die Tabellen angelegt sind.
dann darf er mir den log ausgeben. den da könnte ja eine funktion sein die ein Eintrag in eine Tabelle machen sollte.

Ich will ja lernen! Forme mich...


----------



## CPoly (6. Januar 2012)

Sowohl initDB als auch checkAllDBs müssen natürlich ihre übergebenen Funktionen auch aufrufen.

Am Besten zeigst du mal den ganzen Code.


----------



## Fruitgum (6. Januar 2012)

okay...

hier noch initDB & checkAllDBs


```
function initDB(fn) { 
        
    try {
        
        if (!window.openDatabase) { 
        
          alert('Datenbank wird auf Ihren Gerät nicht unterstützt'); 
        
        } else { 

          var DBshortName = 'test'; 
          var DBversion = '1.0'; 
          var DBdisplayName = 'testDB'; 
          var DBmaxSize = 11048576; // bytes 
          db = window.openDatabase(DBshortName, DBversion, DBdisplayName, DBmaxSize); 
      
        }
       
        if(db) {
        
             console.log('Datenbank inialisiert!');
        
        } else {
          
             console.log('Datenbank nicht inialisiert!');
        
        }
       
	fn(); //callback
       
      } catch(e) { 
 
 
        if (e == INVALID_STATE_ERR) { 
          
          console.log("Falsche Datenbank-Version."); 

        } else {
          
          console.log("Unbekannter Fehler "+e+"."); 
        
        } 
        
        return; 
      
      } 
}
```

und


```
function checkAllDBs(fn) {
 
createTable('tabelle_t','id, version, name, expTypeId, revision, country, locality, distance, durances, climby, descents, Max, heightMax, range, able, ableString, typeId, commentCount, rating, price, imgSrc, creator, creationDate, severity, severityString, shortDescription, description, tags, fbLikeCount, downloadCount, viewCount, contact, link, lat, lon, images, trackpointsObj');	

createTable('tabelle_p', 'id, lat, lon, images, www, phone, fax, email, text, teaser, zip, ort, name, side, address, src, typeId');

createTable('tabelle_news', 'titles, descriptions, date, id');
   
 fn();    //callback

}
```


----------



## CPoly (7. Januar 2012)

initDB scheint schonmal synchron zu sein, also kannst du dir da dein callback sparen. Ich vermute mal der einzige asynchrone code versteckt sich in "createTable". Da wäre auch der Quelltext interessant.


----------



## Fruitgum (7. Januar 2012)

okay dann brauchst auch noch dann den eintrag dazu:


```
function createTable(table, rows) {
	sql = 'CREATE TABLE IF NOT EXISTS '+dbPrefix+table+' ('+rows+')';
	executeQuery(sql,[],function(results){console.log('Create '+dbPrefix+table+' '+ results);});
}
```

und der executeQuery()


```
function executeQuery($query,data, callback) {
   //alert(data+' - '+$query);
     try {
         
         if(window.openDatabase) {

                    db.transaction(function(tx) {
                    
                    tx.executeSql($query,[data],function(tx,result){
                    
                    if(typeof(callback) == "function"){
                            
                            callback(makeDBArray(result));
                    
                    } else {
                            
                            if(callback != undefined){
                           
                                  eval(callback+"(result)");
                           
                             }
                    }
                   
                    }, errorCB, successCB);
           
                    });
 
         }
         
	 } catch(e) {
	    
		console.log(e);
         
	 }
}
```


----------



## CPoly (7. Januar 2012)

Du musst einfach Schritt für Schritt durch gehen. In "createTable" hast du die Callback Funktion und machst nichts weiter als ein console.log. An der Stelle musst du dem Aufrufer aber noch sagen, dass du fertig bist.


```
function initfunc(fn) {
    initDB(function();

    checkAllDBs(function() {
        fn();
    });
}
 
function onLoad() {
          document.addEventListener("deviceready", onDeviceReady, false);
}
 
function onDeviceReady() {
    initfunc(function() {
         // ab hier soll es erst weiter gehen wenn wenn initfunc() fertig ist.
    });
}
```


```
function checkAllDBs(fn) {
 
    createTable('tabelle_t','id, version, name, expTypeId, revision, country, locality, distance, durances, climby, descents, Max, heightMax, range, able, ableString, typeId, commentCount, rating, price, imgSrc, creator, creationDate, severity, severityString, shortDescription, description, tags, fbLikeCount, downloadCount, viewCount, contact, link, lat, lon, images, trackpointsObj', function() {

        createTable('tabelle_p', 'id, lat, lon, images, www, phone, fax, email, text, teaser, zip, ort, name, side, address, src, typeId', function() {

            createTable('tabelle_news', 'titles, descriptions, date, id', function() {

                fn();

            });

        });

    }); 
}
```


```
function createTable(table, rows, fn) {
    sql = 'CREATE TABLE IF NOT EXISTS '+dbPrefix+table+' ('+rows+')';
    executeQuery(sql,[],function(results) {
        console.log('Create '+dbPrefix+table+' '+ results);}
        fn();
    );
}
```


Aber du machst es dir glaube ich unnötig kompliziert. tx.executeSql kann mehrfach ausgerufen werden, um mehrere Queries abzusetzen.


----------



## Fruitgum (7. Januar 2012)

na ich habe das problem das die funktion die den query absetzen will, den executeQuery ein overlow verursacht... habe auch diese fehler meldung

 Storage.executeSql(): Error=bind or column index out of range:


----------



## CPoly (7. Januar 2012)

In welcher Zeile ist dieser Fehler?

Ich kann nur raten: Du übergibst executeQuery als "data" ein leeres Array [] und umschließt es dann beim Aufruf von executeSql nochmal mit eckigen Klammern. Also übergibst du ein leeres, zweidimensionales Array [[]].

Das ist aber wirklich nur in blaue geraten.


----------



## Fruitgum (7. Januar 2012)

na ich fülle das so


```
data = [data[0], data[1]]; //usw
```

im executeQuery() komm das dann schon an, aber ich denke als string.



man soll es so bauen 


```
var data = ['1','chris','2000-02-22 00:00:00.000','170','60', '20', '0'];

transaction.executeSql("INSERT INTO measurements(id, user, date, height, weight, bmi, abnormal) VALUES (?, ?, ?, ?, ?, ?, ?)", [data[0], data[1], data[2], data[3], data[4], data[5], data[6]]);
```


ich habe die inhalte von data anders gemacht...



```
var data = [title, description, dateModified, id, sType]; //das sind variablen
```


ist falsch?


----------



## CPoly (7. Januar 2012)

Ich sehe da keinen Fehler. Die Fehlermeldung deutet darauf hin, dass mit der Anzahl was nicht stimmt. Aber du hast genau so viele Fragezeichen (Platzhalter) wie Spalten und Werte in dem Array. Ich weiß da nicht weiter, habe selbst noch nie mit der Datenbank gearbeitet.


----------



## Fruitgum (7. Januar 2012)

ja irgendwie ist das mit Phonegap nicht das ware. der Zeigt mir auch wie er Lustig ist an ob er nun Online oder Offline ist. Ich hänge heir schon wieder Stunden ohne erfolg.. Vielleicht liegt es auch am Smartphone.

ab und zu kommt auch sowas:


01-07 15:44:32.216: E/JavaBinder(1139): ****** FAILED BINDER TRANSACTION ******


So ein Käse

Kein richtiges Debbuging mit Eclipse möglich. Zeigt mir nur das an was ich mit jeder herkömmlichen Konsole auch geht und der misstige Fileexplorer geht auch nicht. 

Ich mache Schluss für Heute, sonst dreh ich hier noch durch.

Danke für deine Hilfe!


----------

