简体   繁体   中英

Node.JS Recursive Function Bad Variable

I am having a weird issue where if I hardcode a variable, my code works. When the code sets the variable I get weird results. However using console log I can see that the variable IS the correct value. I can literally copy the console value and paste it in place of the variable, and it will work.

function CheckInboxes (boxes, count=0) {
    console.log('-----------------------------------------')
    console.log('checking: ' + boxes[count] + ' | ' + count)
    console.log('-----------------------------------------')

    OpenInbox(boxes[count]).then(box => { //If I set this to 0 or any other value count would be, it works.

        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')
        console.dir(box)
        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')


        if(count < boxes.length -1) {
            var test = count + 1
            CheckInboxes(boxes, test) }
        else
            console.log('FINISHED<<<<<<<<<<<<<<<<<<<<<<<<<<')


    })


}

boxes is an array of mailbox names ie "inbox", "draft", "etc"

The OpenInbox function returns an object defining that inbox (folder). This includes the name. The name should match the first parameter. So OpenInbox('inbox') returns an object with a name property of "inbox" because the library searches for a folder with that name and returns the object associated with it.

The problem is, this is not what happens if its not hardcoded. Its completely random. The returned object could be draft or any other folder. Sometimes it happens to be the right folder.

> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ----------------------------------------- checking: Inbox | 0
> ----------------------------------------- opening...Inbox

This clearly shows its 0 and its passing "Inbox". The result will be random though. HOWEVER, if I replace

OpenInbox(boxes[count])

with

OpenInbox(boxes[0]) //or just 'inbox' 

It works. Of course this isn't practical...

So I am very confused. Console clearly shows whats being passed, yet it doesn't work unless I hardcode the value outputted in console. This shouldn't be possible. Am I missing something?

UPDATE:

So by accident I add this code:

console.dir(box)
        console.log(box.name)
        console.log(JSON.stringify(box))

The result is...

在此处输入图片说明

Notice the underlined parts are completely different.

This leads me to think its a bug in chrome console.log or something because stringify shows the data I'm expecting.

To make promises work properly with recursion and keep the chain in order, you need to return the inner promises so everything is properly chained together. Note the places where I added return :

function CheckInboxes (boxes, count=0) {
    console.log('-----------------------------------------')
    console.log('checking: ' + boxes[count] + ' | ' + count)
    console.log('-----------------------------------------')

    // return this promise
    return OpenInbox(boxes[count]).then(box => {

        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')
        console.dir(box)
        console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')

        if(count < boxes.length -1) {
            // return this promise
            return CheckInboxes(boxes, count + 1);
        } else {
            console.log('FINISHED<<<<<<<<<<<<<<<<<<<<<<<<<<');
            // Is there a proper value to return here?
        }
    });
}

The way you had it, you were creating new independent promise chains which would interleave with each other rather than run serially.


PS There are some known issues with console.log(obj) in Chrome. If you immediately change obj right after you do console.log(obj) , then Chrome might not output what you wanted. It appears that the obj is not immediately copied and the console.log() is not immediately carried out (perhaps because of process boundaries) so if you immediately modify obj , it might get changed before console.log() actually does its work. The usually work-around when you see this happening is exactly what you did (use JSON.stringify()). Fortunately, this doesn't happen that frequently, but when it does it can be very confusing. I'm just very careful in my code to notice if I'm immediately modifying an object that I just output with console.log() and, if so, I either output just the desired property or I use JSON.stringify() .

the boxes could be an object not array. check your boxes with Object.keys(boxes)

if it's string or number ..

{
  "0": {..},
  "1": {..},
}
// OR
{
  0: {..},
  1: {..},
  ...
}

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