Detecting changes before transformations

With Immutable.js collections, the idea is to detect any changes before any transformations and side-effects are run. You could, for example, detect changes after transformations but before side-effects:

const myList = List.of(1, 2, 3);
const mySideEffect = (list) => {
const transformed = list
.map(v => v * v);

if (!transformed.equals(mySideEffect.prev)) {
mySideEffect.prev = transformed;
transformed.forEach(
v => console.log('transformed', v)
);
}
};

mySideEffect(myList);
// -> transformed 1
// -> transformed 4
// -> transformed 9
mySideEffect(myList.set(0, 1));
mySideEffect(myList.push(4));
// -> transformed 1
// -> transformed 4
// -> transformed 9
// -> transformed 16
mySideEffect(myList.push(4));

The mySideEffect() function transforms a list of numbers and then iterates over the results, logging the values. The second and fourth calls to mySideEffect() don't log any values, because we're passing in the same value that was used in the previous call. These values are stored in the prev property of the function, and if the list argument is the same collection, we skip the side-effect.

Skipping side-effects is useful because it means that you don't have to perform expensive operations such as updating DOM nodes or writing to a file.

The problem with this approach is that we're comparing the result of the transformation with a previous transformation result. You don't need to do this. Instead, you should only compare the collection argument itself:

const myList = List.of(1, 2, 3);
const myModifiedList = myList.push(4);

const mySideEffect = (list) => {
if (list !== mySideEffect.prev) {
mySideEffect.prev = list;
list
.map(v => v * v)
.forEach(v => console.log('transformed', v));
}
};

mySideEffect(myList);
// -> transformed 1
// -> transformed 4
// -> transformed 9
mySideEffect(myList.set(0, 1));
mySideEffect(myModifiedList);
// -> transformed 1
// -> transformed 4
// -> transformed 9
// -> transformed 16
mySideEffect(myModifiedList.set(0, 1));

We've introduced two improvements to mySideEffect() here. First, we're detecting changes to the collection before any transformations are run. This could potentially save a lot of computing effort. Second, since we're detecting changes before transformations happen, we only care about mutative methods, which means that we can compare using strict inequality instead of equals(). This is another potential performance improvement.

One downside to mySideEffect() is that it's not a generic solution. Your application will likely have several side-effects. Another downside is that your side-effect functions could need more than a single collection argument in order to transform data needed by the side-effect.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.184.90