Last active
October 4, 2015 05:12
-
-
Save bangedorrunt/77364a14911575be8a25 to your computer and use it in GitHub Desktop.
JavaScript Cookbook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copy from `You Don't Know JS: Async & Performance` book | |
// by Kyle Simpson | |
function asyncify(fn) { | |
var orig_fn = fn, | |
intv = setTimeout(function() { | |
intv = null; | |
if (fn) fn(); | |
}, 0); | |
fn = null; | |
return function() { | |
// Firing too quickly, before `intv` timer has fired to | |
// indicate async turn has passed? | |
if (intv) { | |
fn = orig_fn.bind.apply( | |
orig_fn, | |
// Add the wrapper's `this` to the `bind(..)` | |
// call parameters, as well as currying any | |
// passed in parameters | |
[this].concat([].slice.call(arguments)) | |
); | |
} | |
// Already async | |
else { | |
// invoke original function | |
orig_fn.apply(this, arguments); | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2014 Simon Lydell | |
// X11 (“MIT”) licensed. (see license.) | |
// Module: | |
function asyncify(syncFn) { | |
return function() { | |
var args = Array.prototype.slice.call(arguments) | |
var callback = args.pop() | |
setImmediate(function() { | |
try { | |
callback(null, syncFn.apply(this, args)) | |
} catch (error) { | |
callback(error) | |
} | |
}) | |
} | |
} | |
module.exports = asyncify | |
// Usage: | |
var asyncify = require("simple-asyncify") | |
function addSync(a, b) { | |
if (typeof a !== "number" || typeof b !== "number") { | |
throw new TypeError("add requires two numbers") | |
} | |
return a + b | |
} | |
var add = asyncify(addSync) | |
add(1, 2, function(error, sum) { | |
console.log("The sum is: " + sum) | |
}) | |
add(1, function(error, sum) { | |
console.log(error.message) | |
}) | |
console.log("Let’s do some math!") | |
// Let’s do some math! | |
// The sum is: 3 | |
// add requires two numbers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function curry(func) { | |
var initial_args = [].slice.apply(arguments, [1]); | |
var func_args_length = func.length; | |
function curried(args) { | |
if (args.length >= func_args_length) { | |
return func.apply(null, args); | |
} | |
return function() { | |
return curried(args.concat([].slice.apply(arguments))); | |
}; | |
} | |
return curried(initial_args); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Source: http://tech.pro/blog/2097/clever-way-to-demethodize-native-js-methods | |
var demethodize = function(fn){ | |
return function(){ | |
var args = [].slice.call(arguments, 1); | |
return fn.apply(arguments[0], args); | |
}; | |
}; | |
// Equal to | |
var demethodize = Function.prototype.bind.bind(Function.prototype.call); | |
// Usages: | |
var test = "abc,def,g"; | |
test.split(","); | |
//=> ["abc","def","g"] | |
var split = demethodize(String.prototype.split); | |
split(test,","); | |
//=> ["abc","def","g"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Basic syntax | |
function *foo(x) { | |
var y = x * (yield "Hello"); // Yield a value! | |
return y; | |
} | |
var it = foo( 6 ); | |
var res = it.next(); // First `next`, don't pass anything | |
res.value; // => "Hello" | |
res = it.next( 7 ); // Pass `7` to waiting `yield` | |
res.value; // => 42 | |
// for..of iterator | |
function *foo() { | |
yield 1; | |
yield 2; | |
yield 3; | |
yield 4; | |
yield 5; | |
return 6; // `Returned value` is ignored in generator function | |
} | |
for (var v of foo()) { | |
console.log( v ); | |
} | |
// 1 2 3 4 5 | |
console.log( v ); // Still `5`, not `6` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function* letters() { | |
console.log('a'); | |
yield 'a'; | |
console.log('b'); | |
yield 'b'; | |
while (true) { | |
console.log('c'); | |
yield 'c'; | |
} | |
} | |
var a = letters(); | |
a.next(); | |
a.next(); | |
a.next(); | |
a.next(); | |
// Equivalent to | |
function letters() { | |
var state = 0; | |
return { | |
next: function() { | |
switch (state) { | |
case 0: | |
console.log('a'); | |
state = 1; | |
return { | |
value: 'a', // Return the first yielded value. | |
done: false | |
}; | |
case 1: | |
console.log('b'); | |
state = 2; | |
return { | |
value: 'b', // Return the second yielded value. | |
done: false | |
}; | |
case 2: | |
console.log('c'); | |
return { | |
value: 'c', // Return the third yielded value... forever. | |
done: false | |
}; | |
} | |
} | |
}; | |
} | |
var a = letters(); | |
a.next(); | |
a.next(); | |
a.next(); | |
a.next(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function add(x, y, z) { | |
return x + y + z; | |
} | |
// `apply` call `bind` function with its arguments | |
// This kind of implementation is useful when you want | |
// `bind` takes its arguments as an array, as same as | |
// `apply` function | |
var args = [1, 2]; | |
var addCurryFn = add.bind.apply(add, [this].concat(args)); // [this, 1, 2] is `add.bind` parameters | |
console.log(addCurryFn(3)); // => 6 | |
// Equals to | |
var addCurryFn = add.bind(this, 1, 2); | |
console.log(addCurryFn(3)); // => 6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var MyModules = (function Manager() { | |
var modules = {}; | |
function define(name, deps, impl) { | |
for (var i = 0; i < deps.length; i++) { | |
deps[i] = modules[deps[i]]; | |
} | |
// Many people will have misunderstanding with invoking function | |
// modules[name] = impl(deps) <~~ This will NOT WORK! | |
// Because impl is expected to receive deps as an array of | |
// parameters, but impl(deps) only pass [deps[0]] value. | |
// Hence, the following implementation is correct | |
modules[name] = impl.apply(impl, deps); | |
} | |
function get(name) { | |
return modules[name]; | |
} | |
return { | |
define: define, | |
get: get | |
}; | |
})(); | |
// Demo | |
MyModules.define("bar", [], function() { | |
function hello(who) { | |
return "Let me introduce: " + who; | |
} | |
return { | |
hello: hello | |
}; | |
}); | |
MyModules.define("foo", ["bar"], function(bar) { | |
var hungry = "hippo"; | |
function awesome() { | |
console.log(bar.hello(hungry).toUpperCase()); | |
} | |
return { | |
awesome: awesome | |
}; | |
}); | |
var bar = MyModules.get("bar"); | |
var foo = MyModules.get("foo"); | |
console.log( | |
bar.hello("hippo") | |
); // Let me introduce: hippo | |
foo.awesome(); // LET ME INTRODUCE: HIPPO |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment