简体   繁体   中英

How to properly build a multi-dimensional update-object/array and patch it over an existing multi-dimensional object? (javascript)

I have two applications, the first reads data from memory and then sends this data to the second application, which always holds an object with the latest data.

Currently, I read all the data in application one and send the complete json object to application 2. To make this more efficient, I'd like to only send what has updated and then in application 2, apply these changes.

I've tried sevaral things over the weekend but I can't decide how to properly do it.

Right now, while reading the data from memory (with a function running every 30ms), I check if the values are different from what they were, just before I read them. If so, put them into an update object or array.

Which currently looks like this:

let globalData = {};
let updateList = {};

function readThingsFromMemory() {
  updateList = {};

  for ( ... ) {
    [read memory]
    setData(... , ..., ...);
  }
}

function setData(...1, ...2, ...3) {
  if (globalData[...1][...2] != ...3) {
    if (updateList[...1] === undefined) {
      updateList[...1] = {};
    }
    updateList[...1][...2] = ...3;
  }
  globalData[...1][...2] = ...3;
}

setInterval(() => {
  readThingsFromMemory();

  // Send updateList to application 2 if updateList != empty
}, 30);

This just seems to me like a weird way and I feel like this could be a lot cleaner and maybe even easier.

Would it even be a good idea to first, create a globalData object from readThingsFromMemory() and after that, loop over that object and determine the differences? Or is it better to do this while reading the memory?

Side notes: Using memoryjs to read from memory and using websockets to send the data to application 2. Also note: The data is an object of objects, not just a plain object.

You can use jsondiffpatch to get/apply the delta of two states.

 const prevGrades = [{ name: "Sam", grade: 84 }, { name: "Jack", grade: 93 }, { name: "Will", grade: 64 }, { name: "Ron", grade: 82 }, { name: "Sara", grade: 95 }, { name: "Martha", grade: 71 }]; const currentGrades = [{ name: "Sam", grade: 84 }, { name: "Jack", grade: 93 }, { name: "Oscar", grade: 74 }, { name: "Ron", grade: 82 }, { name: "Sara", grade: 95 }, { name: "Martha", grade: 71 }]; const delta = jsondiffpatch.diff(prevGrades, currentGrades); console.log("delta:", delta); const lastSavedState = [{ name: "Sam", grade: 84 }, { name: "Jack", grade: 93 }, { name: "Will", grade: 64 }, { name: "Ron", grade: 82 }, { name: "Sara", grade: 95 }, { name: "Martha", grade: 71 }]; const updatedState = jsondiffpatch.patch(lastSavedState, delta); console.log("updatedState: ", updatedState);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jsondiffpatch/0.2.5/jsondiffpatch-full.min.js"></script>

You can just use .filter to find changes. Keep in mind that value-based equality only works with primitives.

const memoryData = {
  a: 10,
  b: 12
}

const globalData = {
  a: 11,
  b: 12
}
//find only differences in app 1
const changedEntries = Object.entries(memoryData).filter(([key, val]) => {
  return globalData[key] !== memoryData[key]
})
console.log(changedEntries) //[ [ 'a', 10 ] ]

//send changedEntries to app 2 and patch over global data
const = changedEntries.forEach(([key, val]) => {
  globalData[key] = val
})

console.log(globalData) //{ a: 10, b: 12 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM