我的 Firebase 数据存储中有大约 10,000 条记录,每条记录都附加了一些数据,例如。
productName: {
price: 10.00,
lastChecked: timestamp,
url: 'http://product/url',
imagePath: 'http://product/image/url'
}
我循环遍历每个产品,并检索每个产品数据,然后执行其他任务。
当我只有几百条记录时,一切都正常工作,但现在我已经有了数千条记录(还会有更多记录),当我运行任务时,它会由于 CPU 过载而崩溃,而大多数产品都不会崩溃。 t 执行他们的任务。
我读过有关循环阻塞的内容,并尝试过回调超时,我在几篇文章中读到这些内容有所改进,但还没有设法防止服务器 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 服务运行,而不是网站,因此将在后台运行。
最佳答案
关于这一点:
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
。但是,在使用递归函数时,您还需要克服其他问题(例如堆栈大小限制),因此我建议您不要在您的用例中使用它。
希望我的回答对您有所帮助,如果没有,请随时发表评论,我会再看一下。
关于javascript - 使用 Node 和 Firebase 循环访问数千条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33364189/