2011-01-17 12 views
2

Hier ist ein Code Beispiel:Wie übergebe ich eine Funktion mit nicht statischen Argumenten als Variable in JavaScript an eine andere Funktion?

function DoStuff() 
{ 
    var v1 = $('#htmlControl1').val(); 
    var v2 = $('#htmlControl2').val(); 

    myFunction1(v1, v2, (myFunction2(v1, v2, myFunction3))); 
} 

function myFunction1(v1, v2, completeFunc1) 
{ 
    //ajax code here, using jQuery, that calls 
    //'completeFunc1' in the 'complete:' block 
} 

function myFunction2(v1, v2, completeFunc2) 
{ 
    //ajax code here, using jQuery, that calls 
    //'completeFunc2' in the 'complete:' block 
} 

function myFunction3() 
{ 
    //performs some other tasks 
} 

Die Absicht ist, dass myFunction1 aufgerufen wird, wird der Ajax-Aufruf gemacht werden, und, nach Abschluss myFunction2 rufen, die wiederum das gleiche tun Aufruf myFunction3 auf seinem Fertigstellung.

Das tatsächliche Ergebnis ist, dass myFunction2 Zuerst führt myFunction3 nach Abschluss genannt wird, und gibt null. myFunction1 wird dann mit null als sein Argument für die vollständige Funktion aufgerufen, was zu keiner Aktion bei der Fertigstellung führt (Ich habe Null einchecken dort, so dass das kein Problem ist).

Also, wie mache ich, was ich hier beabsichtige? Wie übergebe ich myFunction2(v1, v2, myFunction3) mit den gegebenen Variablen an myFunction1 als Argument?

Antwort

2

Fancy neue JavaScript-Umgebungen und verschiedene Bibliotheken (Prototype, Functional) eine „bind“ API, die eine Funktion („f“) gegeben und einige Parameter, gibt Ihnen eine Funktion, die, wenn, rufen genannt "f" mit dem gewählten this Wert und dem gewählten Parameter:

var bound = myFunction.bind(something, v1, v2, myFunction3); 

Nun ruft

bound(); 

wird genau sein wie

Manchmal nennen Leute dies "currying", aber es ist wirklich nicht wahr currying, weil die Werte alle zu der Zeit gebunden werden, die "bind()" aufgerufen wird. Trotzdem ist es nützlich und ordentlich. Je nach Lust und Laune ist "bind()" ziemlich einfach zu implementieren; Ich empfehle den Blick auf die Functional.js source code und von dort aus gehen. Die jQuery-Version heißt $.proxy(), ist aber relativ lahm (Argumente können nicht gebunden werden).

+0

Ich weiß nicht, warum jQuery das nicht hat. Sie glauben nicht wirklich an eine Funktion.bind, mit der Sie Argumente und den Kontext für einen Rückruf binden können. Sie würden nur eher Sie schaffen unendlich tiefe Verschlüsse. –

+0

@Juan Mendes gibt es "$ .proxy()", aber es ist nicht wirklich so schön. – Pointy

+0

Ja, Sie können nur den Kontext und nicht die Argumente festlegen. –

1

Wenn Sie möchten, dass dies etwas dynamischer ist, anstatt dass die Funktionen fest codiert sind, wie wäre es, wenn Sie die Funktionsreferenzen in ein Array als drittes Argument platzieren würden. Dann könnte jeder Anruf .shift() einen aus dem Array holen, bis es keine mehr gibt.

function DoStuff() { 
    var v1 = $('#htmlControl1').val(); 
    var v2 = $('#htmlControl2').val(); 

    // Array of subsequent functions----v 
    myFunction1(v1, v2, [myFunction2,myFunction3]); 
} 

function myFunction1(v1, v2, funcs) { 
    $.ajax({url:'something', 
      complete:function() { 
       var func = funcs.shift(); // shift it off the Array 
       if(func) 
        func(v1, v2, funcs); // If there was a function, call it 
      }        // and pass on the arguments. 
    }); 
} 

function myFunction2(v1, v2, funcs) { 
    $.ajax({url:'something', 
      complete:function() { 
       var func = funcs.shift(); // shift it off the Array 
       if(func) 
        func(v1, v2, funcs); // If there was a function, call it 
      }        // and pass on the arguments. 
    }); 
} 

function myFunction3() { 
    // Performs some other tasks 
} 
Verwandte Themen