in context of chrome extension, have click links cause dynamic menus built before revealing page user.
i have click each link twice, once show , once hide. hide click has occur in timeout other script can take on , build menu.
there several of these menus clicked, have created do_menu(find,clicks,cb)
function find
, clicks
jquery selectors , cb
callback.
from client end, looks like:
that.do_menu('<seek menu selector>' ,'<make menu on click selector>' ,function(){that.do_menu('<seek menu selector>' ,'<make menu on click selector>' ,function(){that.do_menu('etc' ,'etc',ugh!)} );} );
at point deciding put these selectors collection , iterate on them, calling done
function. purposes of discussion, lets wanted implement promises here.
the snag hitting don't know go in timeout. here original function.
do_menu:function(find,clicks,cb){ if($(find).length===0){ // menu needs building $(clicks).click(); // show menu settimeout(function(){ $(clicks).click(); // hide menu cb&&cb(); },100); }else{ // menu built, continue cb&&cb(); } }
when try turn function returns promise, stuck.
do_menu_p:function(find,clicks){ var that=this; return new promise(function(res,rej){ // f1! if($find).length===0){ // need build $(clicks).click(); // show settimeout(function(){ // f2! $(clicks).click(); // hide res({status:'did it'}); // not work cuz f1!==f2 ?? }); } }.bind(that)); }
and client like:
var that=this; this.do_menu_p('<menu>','<click>') .then(/*hmmm...??*/ that.do_menu_p.bind(that,'<more>','<args>'))
no, can tell isn't right. yes, suck @ promises.
i find approach of checking if done, only once after 100ms
bad practice. least check repeatedly. like:
do_menu:function(find,clicks,cb){ var ctr = 0; function check(){ if($(find).length===0){ // menu needs building $(clicks).click(); // show menu settimeout(function(){ $(clicks).click(); // hide menu ctr++; if(ctr<10){ check(); }else{ //throw error, avoid infinite checking. } },100); }else{ // menu built, continue cb && cb(); } } check(ctr); }
the same thing promises
do_menu_p:function(find,clicks){ return new promise(function(res,rej){ var ctr = 0; function check(){ if($(find).length===0){ // menu needs building $(clicks).click(); // show menu settimeout(function(){ $(clicks).click(); // hide menu ctr++; if(ctr<10){ check(); }else{ rej(new error("menu cannot built")); } },100); }else{ // menu built, continue res({status:'did it'}); } } check(ctr); }); }
usage can be:
var that=this; this.do_menu_p('<menu>','<click>') .then(function(res){ return that.do_menu_p('<more1>','<args1>')); }).then( function(res){ return that.do_menu_p('<more2>','<args2>')); }).catch( errorhandler);
long story short, basically, then
takes 2 functions attributes, (successcallback, errorcallback) of said promise. , can chain promises returning new promise @ end of each promise.
edit:
a simple fiddle demo
not sure if below method right way it, can give try...
do_menu_p:function(array){ if(!array || array.length<2) return; function innerpromfn(i){ var find = array[i], clicks = array[i+1]; return new promise(function(res,rej){ var ctr = 0; function check(){ if($(find).length===0){ // menu needs building $(clicks).click(); // show menu settimeout(function(){ $(clicks).click(); // hide menu ctr++; if(ctr<10){ check(); }else{ rej(new error("menu cannot built")); } },100); }else{ // menu built, continue res({status:'did it'}); } } check(ctr); }).then(function(res){ i+=2; if(i>array.length){ return res; }else{ return innerpromfn(i); } }); } return innerpromfn(0); }
Comments
Post a Comment