我的Firebase数据存储大约有10,000条记录,每条记录附有一些数据,例如。
productName: {
price: 10.00,
lastChecked: timestamp,
url: 'http://product/url',
imagePath: 'http://product/image/url'
}
我遍历每个产品,每个产品数据都会检索它,然后执行其他任务。
当我只有几百条记录时,我已经完成了所有工作但现在我已经有成千上万(还有更多的记录),当我执行任务时,它崩溃了CPU过载而且大部分产品都没有执行他们的任务。
我已经阅读过关于循环阻塞和在回调中尝试超时的内容,我在一些帖子中读到了一些改进,但尚未成功阻止服务器CPU过载。
这是我从另一篇文章中实现的一个例子。
getProductData = function(product, callback){
ref.child('products/'+product).once('value', function(snapshot) {
callback(snapshot.val(), product);
});
},
queryProductData = function(product){
getProductData(product, function (productData, productKey) {
setTimeout(scrapeProductDetails(product), 2000) //queue for next ping in the next predefined interval
});
},
productLoop = function(productsList) {
for (var product in productsList)
{
setTimeout(queryProductData(product), 2000) //queue job. Every 2 seconds, query_host will be called.
}
}
这是作为Node服务而不是网站运行,因此将在后台运行。
答案 0 :(得分:2)
关于这一点:
for (var product in productsList)
{
setTimeout(queryProductData(product), 2000)
}
这里有两件不太合适的事情:
通过执行setTimeout(queryProductData(product), 2000)
,您已经在计时器启动之前运行了该功能。请查看bind
以解决此问题。
for循环遍历每个产品并创建定时器,因此每个定时器将在同一时刻启动。结果:for循环后2秒,所有函数将同时运行。所以你基本上仍在做所有事情,但是你增加了2秒的延迟。
你可能想要的是这样的结构:
index = 0
function nextProduct() {
productName = productsList[index] // get current product from list
// Do what you need with productName
index++ // Next product
}
setInterval(nextProduct, 2000);
nextProduct
每次调用时都会从列表中获取下一个产品,而setInterval
每2秒会重复调用nextProduct
。
警告:如果nextProduct
同步运行时间超过2秒,则在调用下一个函数时可能无法更新index
,因此它最好在您使用它来获取产品名称时立即更新index
,而不是像我的示例中那样实际更新。
另一种解决方案是在完成后让nextProduct
自行调用,而不是使用setInterval
。但是,在使用递归函数时,还有其他问题(比如堆栈大小限制),您需要克服这些问题,因此我会根据您的用例提出建议。
我希望我的回答对你有帮助,如果不随意发表评论,我会再看看它。