Vyhledávání na webu

javascript - Nechat funkci počkat na dotaz do web SQL


Funkce Primecheck by měla vracet true nebo false podle toho, zda je předané číslo prvočíslem, nebo ne. Pokud je číslo prvočíslem, funkce ho přidá do tabulky PRIMES. Jedná se o algoritmus Sít Erotosthenova, ale ještě není dokončen.

function primecheck (number) {
    var isprime = true;
        if (number%10 == 1 || number%10 == 3 || number%10 == 7 || number%10 == 9) {
        db.transaction(function (tx) {
            tx.executeSql('SELECT * from Primes', [], function (tx, result) {
                for (var i = 1; i < result.rows.length; i++) {
                    if (number%result.rows.item(i)['prime'] == 0) {
                        isprime = false;
                        break;
                    }
                }
                if (isprime) {
                    tx.executeSql('INSERT INTO PRIMES (prime) values (?)', [number]);
                }
                return isprime;
            }, null);
        }, null, null);

    }
    else {
        isprime = false;
        return isprime;
    }
}

Problém: když předám čísla, která nekončí na 1, 3, 7, 9, funkce vrací true, což je v pořádku. Ale když předám jiná čísla, funkce vrací undefined. Předpokládám, že je to proto, že volání funkce „nečeká“, až SQL dotaz skončí, takže musím použít nějaké callback funkce. Ale nefungovalo to.

Odpověď č. 1

Pokud vaše funkce provádí asynchronní operace, nemůže vrátit hodnotu založenou na výsledku těchto asynchronních operací. (Je to proto, že asynchronní funkce se nespustí, dokud není dokončeno aktuální provádění, kvůli jednovláknové povaze JavaScriptu.) Místo toho by vaše funkce měla očekávat callback funkci, která jako argument přijímá hodnotu, která by byla vrácena.

V současné době voláte svou funkci takto:

var isprime = primecheck(someNum);
// now do something with isprime

Ale musíte použít zpětné volání:

primecheck(someNum, function(isprime) {
    // now do something with isprime
});

Stačí přidat druhý argument zpětného volání a volat tento callback místo použití return:

function primecheck (number, callback) {
    var isprime = true;
        if (number%10 == 1 || number%10 == 3 || number%10 == 7 || number%10 == 9) {
        db.transaction(function (tx) {
            tx.executeSql('SELECT * from Primes', [], function (tx, result) {
                //....
                callback(isprime);
            }, null);
        }, null, null);
    }
    else {
        isprime = false;
        callback(isprime);
    }
}

Teď primecheck nic nevrací, ale zpětná volací funkce, kterou předáte do primecheck, bude vyvolána s isprime jako jejím prvním argumentem kdykoli primecheck zjistí prvočíselnost vstupu.