Javascript TypeError:无法读取属性';最新时间戳';未定义的
我发现了很多类似的问题,但我仍然不知道我的代码出了什么问题。似乎我无法读取回调函数中的全局变量值(URL):我想更新回调函数中的URL latestTimestamp值(err,articles)。以下是出错的代码:Javascript TypeError:无法读取属性';最新时间戳';未定义的,javascript,Javascript,我发现了很多类似的问题,但我仍然不知道我的代码出了什么问题。似乎我无法读取回调函数中的全局变量值(URL):我想更新回调函数中的URL latestTimestamp值(err,articles)。以下是出错的代码: var urls=[ {"url": "http://www.economist.com/feeds/print-sections/77/business.xml", "latestTimestamp": new Number(0)}, {"url": "http:
var urls=[
{"url": "http://www.economist.com/feeds/print-sections/77/business.xml", "latestTimestamp": new Number(0)},
{"url": "http://news.sky.com/feeds/rss/home.xml", "latestTimestamp": new Number(0)},
]; // Example RSS Feeds;
// parse RssFeeds from given websites and write them into databse
function parseRssFeeds(collection){
var feed = require('feed-read'); // require the feed-read module
// loop through our list of RSS feed urls
for (var j = 0; j < urls.length; j++)
{
console.log('Original url timestamp is: '+ urls[j].latestTimestamp.toString());
// fetch rss feed for the url:
feed(urls[j], function(err, articles)
{
// loop through the list of articles returned
for (var i = 0; i < articles.length; i++)
{
var message =
{"title": articles[i].title,
"link": articles[i].link,
"content": articles[i].content,
"published": articles[i].published.getTime()};
collection.insert(message, {safe:true}, function(err, docs) {
if (err) {
console.log('Insert error: '+err);
}else{
console.log('This item timestamp is: '+ message.published);
// get the latest timestamp
if (message.published >urls[j].latestTimestamp) {
console.log('update timestamp to be: '+ message.published);
urls[j].latestTimestamp = message.published;
}
}
});// end collection insert
} // end inner for loop
}) // end call to feed method
} // end urls for loop
}
var-url=[
{“url”:http://www.economist.com/feeds/print-sections/77/business.xml,“latestTimestamp”:新编号(0)},
{“url”:http://news.sky.com/feeds/rss/home.xml,“latestTimestamp”:新编号(0)},
]; // RSS提要示例;
//解析给定网站的RSSFeed并将其写入数据库
函数解析器种子(集合){
var feed=require('feed-read');//需要提要读取模块
//循环浏览我们的RSS提要URL列表
对于(var j=0;jurl[j].latestTimestamp){
log('updatetimestamp to:'+message.published');
URL[j].latestTimestamp=message.published;
}
}
});//结束集合插入
}//结束内部循环
})//结束对feed方法的调用
}//结束循环的URL
}
谢谢你的帮助。错误是:
TypeError: Cannot read property 'latestTimestamp' of undefined
at /Users/Laura/Documents/IBM/project/TestList/app.js:244:37
at /Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/collection/core.js:123:9
at /Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/db.js:1131:7
at /Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/db.js:1847:9
at Server.Base._callHandler (/Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/connection/base.js:445:41)
at /Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/connection/server.js:478:18
at MongoReply.parseBody (/Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
at null.<anonymous> (/Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/connection/server.js:436:20)
at emit (events.js:95:17)
at null.<anonymous> (/Users/Laura/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)
TypeError:无法读取未定义的属性“latestTimestamp”
at/Users/劳拉/Documents/IBM/project/TestList/app.js:244:37
at/Users/劳拉/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/collection/core.js:123:9
at/Users/劳拉/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/db.js:1131:7
at/Users/劳拉/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/db.js:1847:9
在Server.Base.\u callHandler(/Users/劳拉/Documents/IBM/project/TestList/node\u modules/mongodb/lib/mongodb/connection/Base.js:445:41)
at/Users/劳拉/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/connection/server.js:478:18
在MongoReply.parseBody(/Users/劳拉/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
在空。(/Users/劳拉/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/connection/server.js:436:20)
在发出时(events.js:95:17)
在空。(/Users/劳拉/Documents/IBM/project/TestList/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)
这可能是一个重复的问题,但我会在这里给出一个答案,因为对于尚未理解基本问题的JavaScript程序员来说,所有重复问题之间的关系往往很难理解
有两种方法可以解决这个问题。一种方法是更改创建回调的方式。不要使用内联匿名函数:
feed(urls[j], function(err, articles)
{
// loop through the list of articles returned
// ...
您将创建另一个返回回调的函数。将URL传递给该函数,返回的函数将使用URL:
function makeFeedResultHandler(url) {
return function(err, articles) {
// loop through the list of articles returned
// ... code as before up to this line:
if (message.published > url.latestTimestamp) {
console.log('update timestamp to be: '+ message.published);
url.latestTimestamp = message.published;
}
// ... etc
};
}
然后你会这样称呼“feed”:
feed(urls[j], makeFeedResultHandler(urls[j]));
关键的区别在于,传递给“feed”的每个函数都有自己的对象的私有副本(好吧,一个要挑剔的引用副本),来自“url”数组,因此它根本不需要引用变量“j”。这就是问题的症结所在:“j”由代码中的所有回调共享。调用回调时,“j”的值等于“url”数组的长度,因此url[j]
是未定义的
另一种方法是使用新的JavaScript实现中提供的.forEach
方法。这种方法将彻底消除“j”:
urls.forEach(function(url) {
console.log('Original url timestamp is: '+ url.latestTimestamp.toString());
// fetch rss feed for the url:
feed(url, function(err, articles)
{
// loop through the list of articles returned
// ... code as previously, substituting "url" for "urls[j]" everywhere
});
});
同样,这确保发送到“feed”函数的每个回调都有其自己的“url”元素副本。扩展@Pointy在您的帖子下评论中所说的内容:
您在MongoDB中使用的插入函数是异步的,但是您将回调视为同步的。在您的循环中基本上发生的是,在您点击collection.insert之前,一切都按计划进行。从这里开始,过程中断,基本上说“我要告诉mongo现在插入一条记录……最终我会期待一个响应。”同时,循环继续到下一个索引,不会同步地等待回调触发
当您启动回调时,您的循环已经完成,并且J不再表示索引,这就是为什么它没有定义。您还可能会使用当前方法获得与您计划的索引不同的索引
我建议重新设计您的循环,以支持节点的异步特性。很奇怪,有一个很棒的库叫做,它使这个过程非常简单。async.each()函数应该可以帮助您完成所要做的事情。这是一个非常常见的问题的实例,它会困住JavaScript程序员,通常是以这种形式出现的—使用索引变量的循环,以及在循环中为异步函数设置回调的代码