Node.JS递归函数错误变量

时间:2017-07-11 04:18:58

标签: javascript arrays node.js recursion memory

我有一个奇怪的问题,如果我对变量进行硬编码,我的代码就可以了。当代码设置变量时,我会得到奇怪的结果。但是使用控制台日志我可以看到变量IS是正确的值。我可以从字面上复制控制台值并将其粘贴到变量的位置,它将起作用。

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是一组邮箱名称,即“收件箱”,“草稿”,“等”

OpenInbox函数返回一个定义该收件箱(文件夹)的对象。这包括名称。名称应与第一个参数匹配。因此,OpenInbox('inbox')返回名称属性为“inbox”的对象,因为库会搜索具有该名称的文件夹并返回与之关联的对象。

问题是,如果没有硬编码,这不会发生。它完全随意。返回的对象可以是草稿或任何其他文件夹。有时它恰好是正确的文件夹。

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

这清楚地显示了它的0和它的传递“收件箱”。结果将是随机的。但是,如果我替换

OpenInbox(boxes[count])

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

有效。当然这不切实际......

所以我很困惑。控制台清楚地显示了传递的内容,但除非我对控制台中输出的值进行硬编码,否则它不起作用。这不应该是可能的。我错过了什么吗?

更新:

所以我偶然添加了这段代码:

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

结果是......

enter image description here

请注意,带下划线的部分完全不同。

这让我认为它是chrome console.log中的一个错误,因为stringify显示了我期待的数据。

2 个答案:

答案 0 :(得分:2)

为了使promises在递归时正常工作并使链保持有序,你需要返回内部promises,以便将所有内容正确链接在一起。请注意我添加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?
        }
    });
}

你拥有它的方式,你创建了新的独立承诺链,它们将相互交错而不是连续运行。

P.S。 Chrome中的console.log(obj)存在一些已知问题。如果您在obj之后立即更改console.log(obj),则Chrome可能无法输出您想要的内容。似乎没有立即复制obj并且不会立即执行console.log()(可能是因为进程边界),因此如果您立即修改obj,它可能会在{console.log()之前被更改1}}实际上是它的工作。当你看到这种情况时,通常可以解决这个问题(使用JSON.stringify())。幸运的是,这种情况并不经常发生,但是当它发生时,它可能会非常混乱。我只是非常小心地在我的代码中注意我是否立即修改了我刚用console.log()输出的对象,如果是这样,我要么只输出所需的属性,要么使用JSON.stringify()

答案 1 :(得分:1)

boxes可能是一个不是数组的对象。使用boxes

检查Object.keys(boxes)

如果是字符串或数字..

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