callback functions

Fluent Interfaces in JavaScript

Fluent interfaces provide a set of chained methods to manipulate a value in an object. It can help turn complex operations involving many steps into a relatively straightforward set of operations while providing a lot of flexibility. Many libraries like jQuery, Mongo DB and so on use this. To demonstrate, here is a simple string manipulator:

function Formatter(message) {
  const self = this;

  self.value = message;
  self.lastAction = function() {};

  const wrap = function(callback) {
    return function() {
      const argsAsArray = [].slice.call(arguments);
      callback.apply(self, argsAsArray);
      self.lastAction = callback.bind(callback, argsAsArray);

      return self;
    }
  }

  self.prefix = wrap(function(prefix) {
    self.value = prefix + self.value;
  });

  self.suffix = wrap(function(suffix) {
    self.value += suffix;
  });

  this.times = wrap(function(times) {
    // -1 since the action has already been done once
    for (let i = 0; i < times - 1; i += 1) {
      self.lastAction();
    }
  });
};

const value = new Formatter('My exciting sentence')
  .suffix('!')
  .times(5)
  .prefix('[')
  .suffix(']')
  .value
console.log(value);
// [My exciting sentence!!!!!]

It is important to use a wrapper function, so that further functions do not accidentally lack self returns due to copy and pasting errors.

Github Location: https://github.com/Jacob-Friesen/obscurejs/blob/master/2017/fluentInterface.js

anonymous asked:

Can you tell us more about baby Jon please? And maybe baby Abby?

Five year old Elaine was very proud of being allowed to hold baby Jonny and carry him around and hold his bottle while he ate. He was way better than her baby dolls. She used to get a little sulky when her turn to hold him was over.

Baby Jonny did not like sink baths. He would wail when you lowered him into the sink, and then after you’d rocked him in the nice warm water for a little while, he would narrow his eyes at you with his little fingers curled into claws until you were done washclothing and rinsing. “That glare is actually really creepy,” Thea said the first time she bathed him. He was only happy again once you’d wrapped him in a towel and put him on your shoulder.

He babbled a lot before he started talking. Just happily ah-bah-bah-ing away and blowing raspberries. Felicity used to hold up the other end of the conversation with perfect equanimity.

Like, ah-bah-guh, and she’d say, “Of course I reached first for lodash, which - oooh, yes, my smart little man, it has a remove tool! And it was mutable! Yay!”

Babbledee bab bab babble.

“I could just pass in the array and get the second element removed.”

Babble bah?

“Right, but that’s actually a problem when you’re looping over the array while mutating it, see?”

Raspberry.

“Mm-hmm. It takes two arguments: the array, and a callback function.”

Their conversations got significantly less technical when he started using actual words.

Baby Abby liked music, and a standard way of quieting her down was to pace the hall and sing to her. Oliver is not now and never has been even a little bit of a singer, but oh god anything to make her stop crying. One night, sleep-deprived and frazzled, literally the only song he could think of was…

“And I swear it’s the last time, and I swear it’s my last try, and we’ll walk in circles around this whole block, walk on the cracks of the same old sidewalks. Then we’ll talk about leavin’ town, yeah, we’ll talk about leavin’, I swear it’s the last time, and I - ”

“Oliver.” Felicity stood there in a nightgown, deep circles under her eyes, and squinted at him. “Look What Happened? Really?”

“You said sing,” he said, hiking her higher on his shoulder as she did that little hiccuping cry that threatened to turn into full-on wails again. “It’s a song. Okay?”

Set in JavaScript

Sets allow you store unique values. So instead of filtering lists for duplicates, items can just be inserted into a set then extracted from. For example, to unify to sets of asynchronous data with no duplicates:

const getFastCars = function(callback) {
  // Simulate async API
  setTimeout(function() {
    callback([
      { name: 'charger', hp: '707' },
      { name: 'elise', hp: '217' },
    ]);
  }, 500);
}

const getGoodHandlingCars = function(callback) {
  // Simulate async API
  setTimeout(function() {
    callback([
      { name: 'miata', hp: '155' },
      { name: 'elise', hp: '217' },
    ]);
  }, 300);
}


const getGoodPerformanceCars = function(callback) {
  let totalResults = new Set(),
      totalCalls = 0;

  const onCallComplete = function(results) {
    results.forEach(function(result) {
      totalResults.add(result.name);
    });

    totalCalls += 1;
    if (totalCalls >= 2) {
      // Note that Array.from has no IE support, only MS Edge
      callback(Array.from(totalResults));
    }
  }

  getFastCars(onCallComplete);
  getGoodHandlingCars(onCallComplete);
}

getGoodPerformanceCars(function(results) {
  console.info(results);
});
// [ 'miata', 'elise', 'charger' ]

Which requires much less setup to get the unique parts. Normally, some kind of map would have to be used, then its keys would have to be extracted.

Unfortunately, sets track uniqueness in objects by reference and not value. So just inserting objects will not ensure they have they are unique in most cases. But for primitives (like Number), they work very well.

Github Location: https://github.com/Jacob-Friesen/obscurejs/blob/master/2017/setObject.js

Memoize in JavaScript

Memoizing saves past results of function calls and returns the cached version if the same arguments are used again. This is good for expensive computations or when you need to do an external call and you know the result will be the same in a given timeframe. Since Fibonacci functions compute Fibonacci Numbers by computing previous Fibonacci numbers they are a perfect example of when memoization is useful:

var fib = function(n) {
    if (n < 2) {
        return n;
    }

    return fib(n - 1) + fib(n - 2);
};

console.log(fib(0));// 0
console.log(fib(1));// 1
// This should take a few seconds on most modern machines:
console.log(fib(40));// 102334155 

The simplist way to cache the results is then to store a private object that will act as a hash. For simplicity purposes, I have restricted this memoize to only work on one argument. This way a hash function does not need to be used:

var memoize = function(callback) {
    var results = {};

    return function(n) {
        if (results[n] !== undefined){
            return results[n]
        }

        results[n] = callback(n);
        return results[n];
    };
};

Then it can make the Fibonacci function much more efficient. Keep in mind the new fib function must be called recursively, not the old one. So you cannot just pass in fib:

var fastFib = memoize(function(n) {
    if (n < 2) {
        return n;
    }

    return fastFib(n - 1) + fastFib(n - 2);
});

// This should run near instantly on most machines:
console.log(fastFib(40));// 102334155
console.log(fastFib(60));// 1548008755920

Github Location: https://github.com/Jacob-Friesen/obscurejs/blob/master/2015/memoize.js

Tutorial: Resizing Videos

***This tutorial is outdated; please click here to go to the new version.***

I wrote a little script to resize videos to fit any post width without distorting their original dimensions, and it’s so neat and functional compared to CSS fixes that I thought that I ought to share it with you all :-)

Keep reading

Casual Day in a Programmer's Family
  • me: Dad is dinner ready yet?
  • dad: No and stop asking! I'll tell you when it's ready.
  • me: No you won't, you're like a callback function with an invalid pointer
  • dad: And you're an incredibly inefficient polling function, insert "CleanYourRoom" into your work queue.
  • me: Fatal error: Unresolved external symbol "CleanYourRoom"
  • dad: link "libmom.a" and recompile
  • me: damn it