2010-10-29 17 views
7

Attualmente utilizzo il database lato client su una webapp html5 per iphone. Nel mio codice ho bisogno di controllare se una riga è presente nel DB locale:API database HTML5: richiesta sincrona

function isStarted(oDB) { 
var ret = null; 
oDB.query(sql,params,function(transaction,result) { 
    if(result.rows.length > 0) { 
     ret = true; 
    } else { 
     ret = false; 
    } 
}); 

return ret; 

}

Purtroppo il ritorno di isStarted() si verifica prima che la funzione di callback e ottengo sempre un "null" valore. Nel W3c spec possiamo vedere un "synchronous-database-api" ma come posso usarlo? C'è un trucco per ottenere il buon valore "ret" con i requisisti asincroni?

Grazie per il vostro aiuto

+0

Mi piace questa domanda. Segnala il problema molto bene. –

risposta

8

Per ottenere un oggetto che implementa DatabaseSync devi chiamare openDatabaseSync(...) invece di openDatabase(...). Non conosco l'iPhone o l'oggetto oDB che possiedi, ma secondo le specifiche ottieni solo il metodo openDatabaseSync in un WebWorker e non nel normale browser Web window. Certamente XMLHttpRequest ha dimostrato che le operazioni sincrone di lunghezza potenzialmente nell'interfaccia utente non sono una buona idea.

Non è possibile eseguire il codice asincrono in modo sincrono o viceversa. Per fare ciò avresti bisogno di funzionalità a livello di linguaggio come i thread o le co-routine che JavaScript non ha. Devi uscire dalle tue funzioni e restituire il controllo al browser per consentirgli di eseguire la richiesta HTTP o la query del database e richiamarti sulla funzione di gestione che hai fornito.

Quindi dovrai riscrivere il tuo codice 'inside-out' per passare le funzioni di callback invece di aspettarti i valori di ritorno, ogni volta che fai qualcosa che coinvolge il database IO.

function tellMeWhenIsStarted(oDB, callback) { 
    oDB.query(sql,params,function(transaction,result) { 
     callback(result.rows.length>0); 
    } 
}); 
+0

State richiamando o richiamandolo? –

+0

Stai chiamando. –

8

Sono l'unico a trovare ridicola questa richiesta asincrona? In più, sembra che Safari implementa solo il modello asincrono in questo momento ... Mi chiedo come viene efficientemente codificato in quel modo ...

Mi piacerebbe qualsiasi collegamento a una seria programmazione con il driver async db.

-1

È necessario bloccare l'esecuzione successiva quando si desidera recuperare i risultati in modo sincrono. Il prezzo da pagare è l'UI che si blocca durante l'esecuzione.

var ret = null; 
var finished = false; 

cfunction isStarted(oDB) { 
     oDB.query(sql,params,function(transaction,result) { 
       ret = result; 
       finished = true; 
     }); 

    while(!finished){ 
    ;//block next execution, while result is being fetched 
    } 
    return ret; 
} 
+1

Sembra non funzionare, almeno in Chromium 17.0.963.56. È anche quello che mi aspetterei, dal momento che JS non ha thread, quindi non solo l'interfaccia utente è bloccata durante il ciclo while, ma anche il recupero effettivo. – keppla