Make function call wait for web SQL query

2019-06-21 22:25发布

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.

1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-06-21 22:46

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.

查看更多
登录 后发表回答