Javascript Node.js上的同步操作(大数据计算)
编辑 对评论所作的修改 我有四个Javascript Node.js上的同步操作(大数据计算),javascript,arrays,node.js,ecmascript-6,array-algorithms,Javascript,Arrays,Node.js,Ecmascript 6,Array Algorithms,编辑 对评论所作的修改 我有四个数组 commonOrdersList——长度约40k storeA——长度接近100k storeB——长度约110k storeC——长度接近100k 不同大小的对象的集合看起来像 [ { "orderId": "someUniqId", "orderTime": 1477764124822 //timestamp } ] 数组中的项没有特定的顺序 我要做的是查找commonOrderlist中是否有任何订单也存在于三家门店中的任何一家,即st
数组
commonOrdersList——长度约40k
storeA——长度接近100k
storeB——长度约110k
storeC——长度接近100k
不同大小的对象的集合看起来像
[
{
"orderId": "someUniqId",
"orderTime": 1477764124822 //timestamp
}
]
数组中的项没有特定的顺序
我要做的是查找commonOrderlist
中是否有任何订单也存在于三家门店中的任何一家,即storeA
、storeB
、storeC
,并通过比较订单时间筛选出最近的订单
这就像在比较三个不同大小的四个数组时获得联合一样
我尝试对commonOrderList
中的每个对象/顺序进行迭代,然后将每个项目传递给其他存储,但这会导致内存堆栈大小超出范围错误
我做了一些类似的事情
function getRecentOrders () {
commonOrderList.forEach(val => {
storeA.forEach(item => {
if (val.orderId === item.orderId && item.orderTime > val.orderTime) {
let orderDetails = {
"orderId": item.orderId,
"orderTime": item.orderTime
}
recentOrders.push(orderDetails);
uniqOrderIdSet.add(orderId);
})
storeB.forEach(item => {
if (val.orderId === item.orderId && item.orderTime > val.orderTime) {
let orderDetails = {
"orderId": item.orderId,
"orderTime": item.orderTime
}
recentOrders.push(orderDetails);
uniqOrderIdSet.add(orderId);
})
storeC.forEach(item => {
if (val.orderId === item.orderId && item.orderTime > val.orderTime) {
let orderDetails = {
"orderId": item.orderId,
"orderTime": item.orderTime
}
recentOrders.push(orderDetails);
uniqOrderIdSet.add(orderId);
})
})
}
超出了此前置内存调用堆栈大小
然后我尝试将上述同步操作放在AsyncsetTimeout
函数中,以避免调用堆栈超出其限制,如:
let recentOrders = [],
uniqOrderIdSet = new Set();
commonOrderList.forEach(val => {
getOrdersFromStoreA(val);
getOrdersFromStoreB(val);
getOrdersFromStoreC(val);
})
function getOrdersFromStoreA(val) {
setTimeout(() => {
storeA.forEach(item => {
if (val.orderId === item.orderId && item.orderTime > val.orderTime) {
let orderDetails = {
"orderId": item.orderId,
"orderTime": item.orderTime
}
recentOrders.push(orderDetails);
uniqOrderIdSet.add(orderId);
})
}, 6000);
}
function getOrdersFromStoreB(val) {
setTimeout(() => {
storeB.forEach(item => {
if (val.orderId === item.orderId && item.orderTime > val.orderTime) {
let orderDetails = {
"orderId": item.orderId,
"orderTime": item.orderTime
}
recentOrders.push(orderDetails);
uniqOrderIdSet.add(orderId);
})
}, 3000);
}
function getOrdersFromStoreC(val) {
setTimeout(() => {
storeC.forEach(item => {
if (val.orderId === item.orderId && item.orderTime > val.orderTime) {
let orderDetails = {
"orderId": item.orderId,
"orderTime": item.orderTime
}
recentOrders.push(orderDetails);
uniqOrderIdSet.add(orderId);
})
}, 8000);
}
但是调用堆栈再次超出。和这也是一个耗时的过程
我还尝试创建<强> > OrdID和<强> OrthTime< /St>。但是,可以有相同的OrthID和不同的OrthPoT项目,所以我也需要考虑这个情况。
那么,有什么方法可以在不超过内存堆栈大小的情况下,在更短的时间内执行此计算呢 任何形式的帮助都将不胜感激 下面是我得到的错误堆栈:{"name":"retail","hostname":"user-lenovo- 80","pid":26525,"level":20,"msg":"Error occurred in getRecentOrders() ===> [
RangeError: Maximum call stack size exceeded]","time":"2016-10-28T10:48:59.668Z","v":0}
RangeError: Maximum call stack size exceeded
at process.nextTick (node.js:478:22)
at onwrite (_stream_writable.js:343:15)
at WritableState.onwrite (_stream_writable.js:89:5)
at WriteStream.Socket._writeGeneric (net.js:690:5)
at WriteStream.Socket._write (net.js:700:8)
at doWrite (_stream_writable.js:300:12)
at writeOrBuffer (_stream_writable.js:286:5)
at WriteStream.Writable.write (_stream_writable.js:214:11)
at WriteStream.Socket.write (net.js:626:40)
at Console.log (console.js:39:16)
这很奇怪,你不应该从简单的数组迭代中得到堆栈溢出。你确定不涉及递归吗?您是否从异常中获得了堆栈跟踪?如果这些数组没有特殊的排序,您基本上不可能找到更有效的解决方案。您当然可以通过某种方式加快当前代码的速度(例如,通过使用循环而不是
forEach
回调调用),但要真正发挥作用,您需要更改存储。究竟为什么您要在内存中保存~350000个对象(至少)并尝试在内存中进行搜索??为什么不使用一个事实上是为高效分页和查询而设计的数据库呢?例如,如果您想将JS作为一种语言使用,那么在MongoDB中,这个查询将非常简单。我看不到您公开的任何代码会这样做,因此我认为您没有公开导致问题的代码。您能指出是哪种代码导致了错误跟踪吗?跟踪引用了getRecentOrders()
。我看不到这方面的代码。我的猜测是,您对代码的哪一部分导致了此错误做出了错误的假设,因此没有向我们披露正确的代码。这很奇怪,您不应该从简单的数组迭代中得到堆栈溢出。你确定不涉及递归吗?您是否从异常中获得了堆栈跟踪?如果这些数组没有特殊的排序,您基本上不可能找到更有效的解决方案。您当然可以通过某种方式加快当前代码的速度(例如,通过使用循环而不是forEach
回调调用),但要真正发挥作用,您需要更改存储。究竟为什么您要在内存中保存~350000个对象(至少)并尝试在内存中进行搜索??为什么不使用一个事实上是为高效分页和查询而设计的数据库呢?例如,如果您想将JS作为一种语言使用,那么在MongoDB中,这个查询将非常简单。我看不到您公开的任何代码会这样做,因此我认为您没有公开导致问题的代码。您能指出是哪种代码导致了错误跟踪吗?跟踪引用了getRecentOrders()
。我看不到这方面的代码。我的猜测是,您对导致此错误的代码部分做出了错误的假设,因此没有向我们披露正确的代码。