![](/img/trans.png)
[英]When debugging a reducer in the browser, why can't I see a variable's value?
[英]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.