繁体   English   中英

为什么Node被变量选择时看不到数组中的元素?

[英]Why can't Node see an element in an array when it is chosen by variable?

在编写的脚本中,我遍历邮箱中的某些消息,并尝试删除已读取的消息。 我遇到的问题是,当我遍历数组时,Node表示无法在给定元素上找到属性ID(删除或查看任何内容都是必需的)。 如果该属性不存在,那会很好,但是当使用util.inspect并指定1而不是iterator变量时,它可以找到并打印该字段。 存在的代码如下所示:

             for(var b = 1; b < length; b++){
                setTimeout(function(){
                  console.log(util.inspect(messageList, false, null));
                  console.log(util.inspect(messageList[1], false, null));
                  console.log(util.inspect(messageList[1].id, false, null));
                  console.log(util.inspect(messageList[b].id, false, null));
                  var delID = messageList[b].id;
                  //console.log(util.inspect(messageList, false, null));
                  if(delID){
                    gmail.users.messages.trash({
                      auth:auth,
                      userId: 'me',
                      id: delID,
                    }, function(err2, delObject){
                      if(err2){
                        console.log("The message with ID: "+ delID + " could not be deleted");
                        console.log(err2);
                        return;
                      }
                      else{
                        console.log(util.inspect(delObject, false, null));
                        console.log("Message was deleted with id: " + delID);
                      }
                    })
                  }
                }, 2000);
              }

上面的几行中messageList具有实际数字而不是变量,显示'157550983b6c1cb'(也打印出撇号)。 在我用b切换的行上,它抛出:

    TypeError: Cannot read property of undefined
       at Timeout.oneTimeout(.......etc)
       at tryOnTimeout(timers.js:232:11)
       at Time.listonTimeout(timers.js:202:5)

这是否意味着不可能在Timeout函数中使用变量b? 如果是这样,我该如何解决需要遍历整个messageList并在删除之间插入中断的问题?

因为setTimeout是异步的,所以在for循环完成之前将不会调用回调-此时,b将为messageList.length-太大

您希望在每次迭代之间等待2秒-一种方法是使用这样的递归函数调用

var length = messageList.length;
function myFunction(b) {
    setTimeout(function() {
        console.log(util.inspect(messageList, false, null));
        console.log(util.inspect(messageList[1], false, null));
        console.log(util.inspect(messageList[1].id, false, null));
        console.log(util.inspect(messageList[b].id, false, null));
        var delID = messageList[b].id;
        //console.log(util.inspect(messageList, false, null));
        if (delID) {
            gmail.users.messages.trash({
                auth: auth,
                userId: 'me',
                id: delID,
            }, function(err2, delObject) {
                if (err2) {
                    console.log("The message with ID: " + delID + " could not be deleted");
                    console.log(err2);
                    return;
                } else {
                    console.log(util.inspect(delObject, false, null));
                    console.log("Message was deleted with id: " + delID);
                }
            })
        }
        b += 1;
        if (b < length) {
            myFunction(b);
        }
    }, 2000);
}
if (messageList.length > 0) {
    myFunction(0);
}
// note - any code here will run immediately! 
// it wont wait for the "iteration" to complete - 
// if you need to wait for the above to finish, 
// that's a whole other set of problems

根据注释,如果您希望第一轮迭代立即运行,请将代码更改为

var length = messageList.length;
function myFunction(b) {
    console.log(util.inspect(messageList, false, null));
    console.log(util.inspect(messageList[1], false, null));
    console.log(util.inspect(messageList[1].id, false, null));
    console.log(util.inspect(messageList[b].id, false, null));
    var delID = messageList[b].id;
    //console.log(util.inspect(messageList, false, null));
    if (delID) {
        gmail.users.messages.trash({
            auth: auth,
            userId: 'me',
            id: delID,
        }, function(err2, delObject) {
            if (err2) {
                console.log("The message with ID: " + delID + " could not be deleted");
                console.log(err2);
                return;
            } else {
                console.log(util.inspect(delObject, false, null));
                console.log("Message was deleted with id: " + delID);
            }
        })
    }
    if (b < length - 1) {
        setTimeout(myFunction, 2000, b + 1);
    }
}
if (messageList.length > 0) {
    myFunction(0);
}
// note - any code here will run immediately! 
// it wont wait for the "iteration" to complete - 
// if you need to wait for the above to finish, 
// that's a whole other set of problems

如果您想让代码在迭代完成时运行,那么使用Promises可以使事情变得更加简单-无论您是否有在完成时运行的代码,都可以使用此方法

messageList
.slice(1) // skip the first item in the array as per question code - remove this line to start at 0
.reduce(function(prom, messageItem, index) {
    return prom
    .then(function () {
        if (index) { // this avoids the 2 second wait on the first item
            return new Promise(function(resolve) {
                setTimeout(resolve, 2000);
            });
        }
    })
    .then(function() {
        console.log(util.inspect(messageList, false, null));
        console.log(util.inspect(messageItem, false, null));
        console.log(util.inspect(messageItem.id, false, null));
        var delID = messageItem.id;
        //console.log(util.inspect(messageList, false, null));
        if (delID) {
            gmail.users.messages.trash({
                auth: auth,
                userId: 'me',
                id: delID,
            }, function(err2, delObject) {
                if (err2) {
                    console.log("The message with ID: " + delID + " could not be deleted");
                    console.log(err2);
                    return;
                } else {
                    console.log(util.inspect(delObject, false, null));
                    console.log("Message was deleted with id: " + delID);
                }
            });
        }
    });
}, Promise.resolve()) // this starts the promise chain
.then(function() {
    // this code gets called once the "loop" finishes
});
// code here does not wait for the "loop" to finish
// in fact it runs before the first messageList item is even processed

此代码不会等待gmail.users.messages.trash开始等待下一次迭代之前完成-如果你需要等待,然后再次,这是一个整体的其他问题,但很很容易使用时处理承诺方法

这主要是因为setTimeout是异步的。

您可以尝试这样的事情:

for(var a = 1; a < 10; a++) {
    (function(){
        var currentI = a;
        setTimeout(function(){
                console.log('Hi: sec: ', currentI);
        }, 1000);
    }());
}

内用一个变量,会帮助你保持其状态可以检查这个了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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