Reputation: 3258
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.
Upvotes: 0
Views: 201
Reputation: 707556
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.
P.S. 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()
.
Upvotes: 2
Reputation: 3939
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: {..},
...
}
Upvotes: 1