Last active
October 26, 2016 13:22
-
-
Save finwo/0ed1d02ec7df2cbf99367e3863002a9b to your computer and use it in GitHub Desktop.
Simple function chaining library.
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(exports) { | |
function Chained(callback) { | |
// Some vars we'll use | |
var chain = [], | |
self = this, | |
ran = false; | |
// Adding more callbacks | |
this.then = function(callback) { | |
// Handle arrays | |
if (callback.forEach) { | |
callback.forEach(self.then); | |
return self; | |
} | |
// Make sure it's a function | |
if (typeof callback !== 'function') { | |
throw "Callback is not a function" | |
} | |
// Add to the chain | |
chain.push(callback); | |
// Kickstart again if we're history | |
if (ran) { | |
this.exec(); | |
} | |
return self; | |
}; | |
// Kickstart the chain.. Blocks until the first async call | |
this.exec = function(persistentData, done) { | |
// We're not history | |
ran = false; | |
// Loads the next call | |
(function run(data) { | |
var allowReturnValue = true; | |
// Allow deep chaining | |
if (data && data.constructor === Chained) { | |
chain.unshift(data.exec); | |
allowReturnValue = false; | |
data = undefined; | |
} | |
// Fetch the call next in line | |
var f = chain.shift(); | |
// If we're done, use either callback or return | |
if (!f) { | |
// Jep, we're history | |
ran = true; | |
if (typeof done === 'function') return done(data); | |
return data; | |
} | |
// Start the call | |
var returnValue = f.call(null, data, run); | |
// Assume return on true-like value | |
if (allowReturnValue && returnValue) { | |
return run(returnValue); | |
} | |
})(persistentData); | |
return self; | |
}; | |
// Allow a function inside the constructor | |
if ('function' == typeof callback) { | |
this.then(callback); | |
} | |
if (callback === true) { | |
this.exec(); | |
} | |
} | |
exports.chained = Chained; | |
if (typeof define === 'function' && define.amd) { | |
define('chained', function() { | |
return Chained; | |
}) | |
} | |
// Attach to window as well | |
if (typeof window !== 'undefined') { | |
window.Chained = Chained; | |
} | |
})(typeof exports === 'object' && exports || this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment