简体   繁体   中英

Javascript function always returns 0

I am writing a function which searches for a value in my IndexedDB and if it finds one, then it should return 1, else it should return 0. The problem is that it always returns 0 though the value exists in a database (variable arr is incremented, but 0 is returned as a result). The code is as follows:

searchAllValues: function(store, type) 
{
    var arr = 0;
    AAA.initDb(function() 
    {
        var obj = {};
        AAA.aaaDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store) 
        {
            var storeresult = store.target.result;
            if(storeresult.value.value == type ){
                arr++;
            }else{console.log('value NOT found');}
            storeresult ? (obj[storeresult.key] = storeresult.value.value, storeresult["continue"]()) : callback(obj)
        }

    });if(arr!=0){return 1}else{return 0}
}

EDIT_1: Ok, I have refactored the code as follows:

addInfo: function(store, type, info) 
{
    var arr = [];
    P4S.p4sPushDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store) 
    {
        var storeresult = store.target.result;
        console.log('value of storeresult==>'+storeresult.value.value);
        if(storeresult.value.value == info)
        {
            arr.push(storeresult.value.values);return;//If it finds something it should stop here, no more search or anything to be done
        }else
        {
            console.log('continuing..');
            storeresult['continue']();
        }
            console.log('arr length==> '+arr.length);//If it finds nothing after the looping the whole DB, I want it to print this statement, only once (to send it to my DB actually but sending code is omitted for simplicity).
    }  

}

Instead I get console.log('arr length==>') statement executed 2 times, for every key in my object store (there are 2 of them actually). So it is doing the code when it finds nothing AND when it finds the value in the DB. Any ideas how to fix it?

Any ideas would be welcome, Thank You

Because by the time the line if(arr!=0){return 1}else{return 0} is executed the db transaction is not complete and value of arr is 0. Though never used indexedDb, but webSql do take some extra miliseconds to read from DB.

Try to put your return logic inside the onsuccess function where you incrementing the arr. You can simply test it by printing value of arr just before your return logic

You need to learn about how to write asynchronous javascript. There are several other indexedDB questions where there are explanations as to why this happens.

For example: Uncaught TypeError: Cannot read property 'transaction' of null with an indexeddb

function addInfo(store, type, info, next) 
{
    var arr = [];
    P4S.p4sPushDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store) 
    {
        var storeresult = store.target.result;
        console.log('value of storeresult==>'+storeresult.value.value);
        if(storeresult.value.value == info)
        {
            arr.push(storeresult.value.values);
            next(arr);//If it finds something it should stop here, no more search or anything to be done
        }else
        {
            console.log('continuing..');
            storeresult.continue();
        }

            console.log('arr length==> '+arr.length);//If it finds nothing after the looping the whole DB, I want it to print this statement, only once (to send it to my DB actually but sending code is omitted for simplicity).
    }
}

Added an extra parameter called 'next' to your the addInfo function. 'next' param is the very last function called if the condition (storeresult.value.value == info) is true. The next function which you create, will use the 'arr' variable and do whatever with it

your 'return statement' doesnt work the sameway with asynchronous functions, would highly advice you search up asynchronous functions to get a gist of how its different to regular functions

This is how you would call your newly edited function:

addInfo(store,type,info,function(arr){
  //do something with arr
})

Note that you have a potential state which would break your code what if the cursor reaches the end of its iterations and never meets that condition (storeresult.value.value == info). storeresult would be null, and the check for the condition ( null .value.value == info) will throw an exception

correction:

function addInfo(store, type, info, next) 
{
    var arr = [];
    P4S.p4sPushDb.transaction(store).objectStore(store).openCursor().onsuccess = function(store){
        var storeresult = store.target.result;

        if(storeresult){
          if(storeresult.value.value == info){
             arr.push(storeresult.value.values);
             next(arr);
          }else storeresult.continue();
        }else next();
    }
}

And when you call it you handle the scenario whereby arr == null

addInfo(store,type,info,function(arr){
  if(arr){
    //do something with arr
  }else{
    //do somethingelse when arr == null
  }
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM