Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/* async method chaining pattern jquery reflection.
this a en example of how to reflect the jquery / any object into a proxy and use
async method chaining pattern is discussed here by dustin diaz of twitter
http://www.dustindiaz.com/async-method-queues/
*/(function($){
var Queue = function(chain){this.q = chain||[]};
Queue.prototype = {
q:[],
flushed:false,
add:function(method,args){
console.log('adding to queue:',method,args);
this.q.push({cb:method,args:args||[]});
},
flush:function(context){
if(!this.flushed){
this.flushed = context
while(this.q.length){
var callable = this.q.shift()||{};
//run the callback but keep the original context
(context[callable.cb]||$.noop).apply(context,callable.args);
}
}
}
};
var FnProxy = function(q,reflect){
var z = this,k;
z._fp_set_queue(q);
z._fp_reflect(reflect);
return this;
};
FnProxy.prototype = {
_fp_queue:[],
_fp_set_queue:function(q){
this._fp_queue = q;
},
_fp_reflect:function(reflect){
var z = this;
for( k in reflect){//yes this is an unfiltered for in
(function(k){
if(typeof(reflect[k]) == 'function'){
z[k] = function(_reflected_name){
if(_reflected_name == '_reflected_name'){
return k;
} else {
z._fp_queue.add(k,arguments);
return z;
}
};
} else {
if(Object.__defineGetter__){
z.__defineGetter__(k,function(){
return reflect[k];
});
z.__defineSetter__(k,function(v){
reflect[k] = v;
});
} else {
z[k] = reflect[k];//copy =( hopefully objects will be refs
}
}
}(k));
}
}
}
$.asyncSelect = function(fn,jqueryResult){
var q = new Queue();
var fn_proxy = new FnProxy(q,jqueryResult||$());
fn.call(this,function(data){
q.flush($(data));
});
return fn_proxy;
};
$.fn.appendAndSelect = function(markup){
var target = this;
return $.asyncSelect(function(cb){
setTimeout(function(){
markup = $(target).append(markup);
cb(markup);
},5000);
},this);
}
$(function(){
var tests = [
{
name:"reflect basic object",
test:function(){
var obj = {
data:'',
lala:function(){
this.data +='lala';
return this;
},
tata:function(){
this.data +='tata';
return this;
}
};
var q = new Queue();
var fnProxy = new FnProxy(q,obj);
obj.lala().tata();
fnProxy.lala().tata();
q.flush(obj);
return obj.data == "lalatatalalatata";
}
},
{
name:"reflect jquery",
test:function(){
var jq = $("#replace_me");
var q = new Queue();
var fnProxy = new FnProxy(q,jq);
fnProxy.html("burrito!");
q.flush(jq);
return $("#replace_me").html() == 'burrito!';
}
}
];
if(!window.console){
var logger = $("<div>").appendTo('body').css({
height:"120px",
backgroundColor:'#fff',
padding:'4px',
margin:'15px;',
border:'2px inset #999',
borderRadius:'5px',
'-moz-border-radius':'5px',
'overflow-y':'scroll'
}).append('<div class="holder"></div>')[0];
console = {
log:function(){
this._log_it(arguments,"<div></div>");
},
info:function(){
this._log_it(arguments,"<div style='color:blue;'></div>");
},
warn:function(){
this._log_it(arguments,"<div style='color:orange;'></div>");
},
_log_it:function(args,html){
var msg = '';
$.each(args,function(k,v){
msg += v.toString();
});
var holder = $(logger).find('.holder');
$(html).html(msg).appendTo(holder);
logger.scrollTop = holder.innerHeight();
}
};
}
$.each(tests,function(i,test){
console.log(test.name)
if(test.test()){
console.info('pass!');
} else {
console.warn('fail!');
}
});
});
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.