Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When can I use lodash.after()?

I'm new to functional programming, and someone recommended lodash for understanding major higher-order functions.

Browsing lodash API docs, I couldn't grasp the sample code for _.after():

var saves = ['profile', 'settings'];

var done = _.after(saves.length, function() {
  console.log('Done saving!');
});

_.forEach(saves, function(type) {
  asyncSave({ 'type': type, 'complete': done });
});
// → logs 'Done saving!', after all saves have completed

The sample code above didn't implement asyncSave(), so I should implement the function for myself. But I have no idea how to implement it. It's because I don't understand the specification of _.after() itself.

It'll be great if someone explains the function easier than the API docs says. Or an easy-to-understand and practical example for the function would be a big help. Thanks!

like image 431
philipjkim Avatar asked Jan 25 '14 13:01

philipjkim


1 Answers

_.after takes as arguments a count n and a function f, and it returns a new function which we could call fp (for "f prime"). The function fp is such that it keeps a count of how many times it has been called. As long as the number of times fp is called is less than n, calling fp does nothing (other than keep the count of times it was called). Once the number of times fp is called is equal or greater than n, f is called.

So:

var _ = require("lodash");
var fp = _.after(3, function () { console.log("OMG!"); });
fp(); // Nothing
fp(); // Nothing
fp(); // Prints "OMG!"

The function asyncSave would be something that performs a save operation asynchronously for a given type of data (the type field in the object passed to it), and upon finishing the save operation calls a callback (the complete field in the object passed to it) exactly once.

So the _forEach loop calls asyncSave once per item in saves meaning that one save operation is launched per item in saves. Since done is the callback for asyncSave, eventually done will be called, once per save operation. Because done was created with _.after and the count passed to _.after was equal to saves.length, the anonymous function passed to _.after won't actually execute until done has been called saves.length times. In other words, it won't be called until all save operations launched in the example are complete.

like image 84
Louis Avatar answered Oct 21 '22 13:10

Louis