Make function call wait for web SQL query
Asked Answered
B

1

6

Primecheck function is supposed to return true or false whether passed number is prime or not. If the number is prime, function adds it to PRIMES table. This is a Sieve of Eratosthenes algorithm, but it's not finished yet.

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

Problem: when I pass numbers that do not end on 1, 3, 7, 9, function returns true, it's ok. But when I pass other numbers, function returns undefined. I suppose it's because function call doesn't "wait" for SQL query to finish, so I must use some kind of callback functions. But it didn't work.

Birdiebirdlike answered 17/9, 2012 at 14:53 Comment(1)
Pass the callback as the second argument of primecheck, and execute callback(isprime) instead of return isprime. (Also, you don't need to select primes which are larger than sqrt(number)).Eigenvalue
L
7

If your function performs asynchronous operations, it cannot return a value based on the result of those asynchronous operations. (This is because the asynchronous functions won't run until the current execution is finished, due to the single-threaded nature of JavaScript.) Instead, your function should expect a callback function that takes the would-be return value as an argument.

You currently call your function like:

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

But you need to use a callback:

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

Just add a second callback argument, and call that callback instead of using a 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);
    }
}

Now, primecheck returns nothing, but the callback function you pass into primecheck will get fired with isprime as its first argument whenever primecheck determines the primality of the input.

Laos answered 17/9, 2012 at 15:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.