Re: how to walk async recursively over an object, doing work (in right order) per leaf

From: Date: Thu, 14 Jun 2012 14:38:47 +0000
Subject: Re: how to walk async recursively over an object, doing work (in right order) per leaf
References: 1  Groups: php.general 
Request: Send a blank email to php-general+get-318234@lists.php.net to get a copy of this message
I think I've got it figured out now.. My solution is to async build up a flat list of items (from the recursive object) to process first, then do another async loop (which I'll build soon) to do the work per item, and when that's done, replace the placeholder with the result. This code works on a custom datastructure that looks like this; { hmData : { mijnDataA : 'a', mijnDataB : 'b', mijnSubKeyA : { hmData : { mijnDataX : 'x' }, hmSettings : { // app-specifc values for the object with key 'mijnDataX' } } }, hmSettings : { // app-specific values for the object with keys 'mijnDataA', 'mijnDataB', and 'mijnSubKeyA' } } Then, the actual code to build up a flat work list of this recursive array, up to a certain level deep (levelsAtOnce) is; printNextLevel : function (pvCmd) { if ( typeof pvCmd.val == 'object' && typeof pvCmd.val.hmStats == 'object' && typeof pvCmd.val.hmData == 'object' ) { //if (pvCmd.keyValueName && pvCmd.keyValueName!='') pvCmd.val.hmStats.keyValueName=pvCmd.keyValueName; //bit of a hack, i agree. var td = typeof pvCmd.val.hmData; var d = pvCmd.val.hmData; } else { var td = typeof pvCmd.val; var d = pvCmd.val; }; rajmv.hms.tools.printNextLevel_scan (pvCmd, rajmv.hms.tools.printNextLevel_buildDatanodes); return { html : '<tr><td>Have Yet To Render This</td></tr>' }; }, printNextLevel_scan : function (pvCmd, callback) { if (!pvCmd.scanResults) { pvCmd.scanResults = [{level:1, datanode:pvCmd.scanPointer}]; pvCmd.scanIdx = 0; pvCmd.scanCount = 0; pvCmd.lastPause = 0; pvCmd.scanCallback = callback; } rajmv.hms.tools.printNextLevel_scanItem (pvCmd); pvCmd.scanCount++; //rajmv.log (2, 'pvCmd.scanIdx='+pvCmd.scanIdx+', scanResults.length-1='+(pvCmd.scanResults.length-1)); if (pvCmd.scanIdx==pvCmd.scanResults.length-1) { if (typeof pvCmd.scanCallback=='function') { pvCmd.scanCallback (pvCmd); } return true; // scanning done! } var pauseFactor = pvCmd.scanCount / 7; if (pauseFactor > pvCmd.lastPause + 1) { setTimeout (function () { pvCmd.lastPause = pauseFactor; rajmv.hms.tools.printNextLevel_scan(pvCmd); }, 50); } else { rajmv.hms.tools.printNextLevel_scan(pvCmd); }; return false; // not done yet }, printNextLevel_scanItem : function (pvCmd) { var it = pvCmd.scanResults[pvCmd.scanIdx]; if (!it || !it.datanode) return false; var tit = typeof it.datanode; if (tit=='object' && it.datanode!==null && it.datanode!==undefined) { if (!it.keys && it.level<=pvCmd.levelsAtOnce) { it.keys = Object.keys (it.datanode); it.keyIdx = 0; } } if (it.keys) { if (it.keyIdx<it.keys.length) { var doUntil = it.keyIdx+20; while (it.keyIdx<doUntil && it.keyIdx<it.keys.length-1) { rajmv.hms.tools.printNextLevel_scanKey (pvCmd); it.keyIdx++; pvCmd.scanCount++; if (it.keyIdx==it.keys.length-1) { pvCmd.scanIdx++; pvCmd.scanCount++; } var pauseFactor = pvCmd.scanCount / 7; if (pauseFactor > pvCmd.lastPause + 1) break; } } } else { pvCmd.scanIdx++; pvCmd.scanCount++; } }, printNextLevel_scanKey : function (pvCmd) { var it = pvCmd.scanResults[pvCmd.scanIdx]; if (!it.keys[it.keyIdx]) debugger; pvCmd.scanResults.splice(pvCmd.scanIdx+1, 0, {level:it.level+1, datanode:it.datanode[it.keys[it.keyIdx]].hmData}); // insert next datanode just after the scanIdx rajmv.log (2, 'hms.tools.printNextLevel_scanKey(): pvCmd.scanCount='+pvCmd.scanCount); }, printNextLevel_buildDatanodes : function (pvCmd) { if (!pvCmd.html) pvCmd.html = ''; // this is where the flat list is ready to be processed (into HTML in my case); debugger; },

« previous php.general (#318234) next »