How to log the program flow of a very deep and complex functional JavaScript code? -
i'm trying understand flow of functions in reselect library. use console.log
log output. still, hard understand flow. make me think how complex functional programming is!!!
how can intercept calls , log function name , parameters console es6 decorator or proxy or other language features?
function defaultequalitycheck(a, b) { return === b } function areargumentsshallowlyequal(equalitycheck, prev, next) { if (prev === null || next === null || prev.length !== next.length) { return false } // in loop (and not `foreach` or `every`) can determine equality fast possible. const length = prev.length (let = 0; < length; i++) { if (!equalitycheck(prev[i], next[i])) { return false } } return true } function defaultmemoize(func, equalitycheck = defaultequalitycheck) { let lastargs = null let lastresult = null console.log("entering defaultmemoize"); console.log("###input### defaultmemoize argument func type: " + typeof func); // reference arguments instead of spreading them performance reasons return function () { if (!areargumentsshallowlyequal(equalitycheck, lastargs, arguments)) { // apply arguments instead of spreading performance. lastresult = func.apply(null, arguments) } lastargs = arguments return lastresult } } function getdependencies(funcs) { const dependencies = array.isarray(funcs[0]) ? funcs[0] : funcs if (!dependencies.every(dep => typeof dep === 'function')) { const dependencytypes = dependencies.map( dep => typeof dep ).join(', ') throw new error( 'selector creators expect input-selectors functions, ' + `instead received following types: [${dependencytypes}]` ) } return dependencies } function createselectorcreator(memoize, ...memoizeoptions) { console.log("entering createselectorcreator"); console.log("#input# argument memoize name: " + memoize.name); console.log("#input# argument memoize options: "); console.log(memoizeoptions); return (...funcs) => { let recomputations = 0 const resultfunc = funcs.pop() const dependencies = getdependencies(funcs) console.log("##input## argument funcs: "); console.log(resultfunc); const memoizedresultfunc = memoize( function () { recomputations++ // apply arguments instead of spreading performance. return resultfunc.apply(null, arguments) }, ...memoizeoptions ) console.log("memoizedresultfunc: " + typeof memoizedresultfunc); // if selector called exact same arguments don't need traverse our dependencies again. const selector = defaultmemoize(function () { const params = [] const length = dependencies.length if (arguments != null) { console.log("***input*** arguments: "); console.log(arguments); } (let = 0; < length; i++) { // apply arguments instead of spreading , mutate local list of params performance. params.push(dependencies[i].apply(null, arguments)) } // apply arguments instead of spreading performance. return memoizedresultfunc.apply(null, params) }) selector.resultfunc = resultfunc selector.recomputations = () => recomputations selector.resetrecomputations = () => recomputations = 0 return selector } } const createselector = createselectorcreator(defaultmemoize) function createstructuredselector(selectors, selectorcreator = createselector) { if (typeof selectors !== 'object') { throw new error( 'createstructuredselector expects first argument object ' + `where each property selector, instead received ${typeof selectors}` ) } const objectkeys = object.keys(selectors) return selectorcreator( objectkeys.map(key => selectors[key]), (...values) => { return values.reduce((composition, value, index) => { composition[objectkeys[index]] = value return composition }, {}) } ) } const shopitemsselector = state => state.shop.items const taxpercentselector = state => state.shop.taxpercent const subtotalselector = createselector( shopitemsselector, items => items.reduce((acc, item) => acc + item.value, 0) ) const taxselector = createselector( subtotalselector, taxpercentselector, (subtotal, taxpercent) => subtotal * (taxpercent / 100) ) const totalselector = createselector( subtotalselector, taxselector, (subtotal, tax) => ({ total: subtotal + tax }) ) let examplestate = { shop: { taxpercent: 8, items: [ { name: 'apple', value: 1.20 }, { name: 'orange', value: 0.95 }, ] } } console.log(subtotalselector(examplestate))// 2.15 //console.log(taxselector(examplestate))// 0.172 //console.log(totalselector(examplestate))// { total: 2.322 }
Comments
Post a Comment