मैं हाल ही में एक परियोजना में काफी है कि का एक सा कर रहा हूँ। मैंने इसे प्रबंधित करने में मदद के लिए कुछ कोड लिखा है। कोड यहाँ है। आप bundledAsync को "कॉल" पैरामीटर और "बंडल कॉलबैक" पैरामीटर वाले ऑब्जेक्ट को पास करते हैं। कॉल पैरामीटर उस कार्य का प्रतिनिधित्व करने वाले objets की एक सरणी है जिसे आप कॉल करना चाहते हैं। एफएन param में, आप वास्तविक पैरामीटर का संदर्भ संग्रहीत करते हैं। "Args" param में, आप अपने तर्क संग्रहीत करते हैं। आपके द्वारा पारित किए गए प्रत्येक कार्य का अंतिम तर्क कॉलबैक होना चाहिए, जिसे कॉल किया जाना चाहिए।
मैं अपने कोड को दस्तावेज करने और इसे दूसरों के लिए उपयोगी बनाने में दुखी हूं, लेकिन यह वास्तव में मेरे लिए वास्तव में उपयोगी है। मुझे संदेह है कि किसी और ने कुछ ऐसा लिखा है, शायद सही ढंग से प्रलेखित। अगर आपको यह नहीं मिल रहा है, और इसे समझने में मदद की ज़रूरत है, तो मुझे बताएं।
/**
This is a way to submit multiple async calls, and be notified when they've all finished
<pre>
NameSpace.bundledAsync({
calls:[
{
fn: service.getGroups,
args: [
function(listsArg){
listsSummary = listsArg;
}
],
calls: function(){return UNAB.Util.makeArray(listsSummary, function(list){
return {
fn: service.getGroup,
args: [list.id, function(resp){listsDetail.push(resp)}]
}
})}
}
],
bundleCallback: function(){
callback(listsDetail)
}
});
</pre>
@class bundledAsync
@static
*/
NameSpace.bundledAsync = function(options){
var callbacksLeft = 0;
var calls = $.grep(options.calls, function(call){return call});
if(options.hasOwnProperty("bundleCallback") && typeof options.bundleCallback != "function"){
throw new Error("bundleCallback, passed to bundledAsync, must be a function.");
}
if(options.chain){ // if this is true, sibling calls will run in succession, not in parallel
calls.reverse();
var newCalls = [calls.pop()];
var lastCall = newCalls[0];
while(calls.length > 0){
if(lastCall.calls){
throw new Error("You can't nest calls if you're in chain mode");
}
lastCall.calls = [calls.pop()];
lastCall = lastCall.calls[0];
}
calls = newCalls;
}
var decrimentCallbacksLeft = function(){
if(options.name){
// log.debug("Starting decrimentCallbacksLeft for: " + options.name + ". Decrimenting callbacksLeft to: " + (callbacksLeft - 1));
}
if(--callbacksLeft == 0 && options.bundleCallback){
// log.debug("No callbacks left. Calling bundleCallback for name: " + options.name);
options.bundleCallback();
}
}
var doCalls = function(callsToDo){
if(typeof callsToDo == "function"){
callsToDo = callsToDo();
}else{
callsToDo = $.extend(true, [], callsToDo);// in case we want to reuse the calls
}
// right away, return if the calls are empty
// check to make sure callbacksLeft == 0, because
// we may be dealing with nested calls
if(callsToDo.length ==0 && callbacksLeft == 0){
// log.debug("callsToDo is empty, so call the callback right away.");
options.bundleCallback();
return null;
}
callbacksLeft += callsToDo.length;
$.each(callsToDo, function(index, call){
var numFns = 0;
// // Look through the args searching for functions.
// // When one is found, wrap it with our own function.
// // This assumes that each function has exactly one
// // callback, and that each callback is called exactly once
// args can be a function which will return the args,
// that way, you don't have to determine the args for the function until the moment it's called
call.args = call.jitArgs? call.args():call.args;
$.each(call.args, function(index, arg){
if(typeof arg === "function"){
numFns++;
// Here's where we wrap the original function's callback
call.args[index] = function(){
// when we get to this point, we know that the original function has totally completed,
// and we can call any functions chained to this one, or finish the whole process
arg.apply(null, arguments); // call the original callback
if(call.calls){
// maybe we don't want to create the child calls until after
// the parent has returned. In that case, pass a function instead of an array
if(typeof call.calls === "function"){
call.calls = call.calls();
}
// if this call has any call of its own, send those out now
doCalls(call.calls);
}
decrimentCallbacksLeft();
}
}
});
if(numFns!=1){
throw new Error("Each function passed to bundledAsync must have one and only one arg which is a function");
}
// if(call.fn.length != call.args.length){
// log.warn("The current function is being called with a different number of arguments that that with which it was declared. Should be: "+call.fn.length+", was: "+call.args.length+" \n" + call.fn.toString());
// }
call.fn.apply(null, call.args);
});
}
doCalls(calls);
}
... क्या आप कृपया अधिक विस्तार से समझा सकते हैं कि आप क्या करना चाहते हैं? – deceze
मैं इस प्रवाह नियंत्रण को लिखना चाहता हूं, लेकिन मुझे नहीं पता कि कैसे। मैंने बहुत सारे कोड के माध्यम से ब्राउज़ किया, लेकिन मुझे यह नहीं मिला। –
क्या कार्य संभावित रूप से असीमित हैं? – slebetman