如何将具有非静态参数的函数作为javascript中的变量传递给另一个函数?

时间:2011-01-17 18:02:51

标签: javascript jquery ajax arguments

以下是一些示例代码:

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
}

目的是调用myFunction1,进行ajax调用,并在完成后调用myFunction2,然后调用myFunction3来调用myFunction2完成。

实际结果是首先调用myFunction3,在完成时执行null,然后返回myFunction1。然后使用null作为完整函数的参数调用myFunction2(v1, v2, myFunction3),导致对其完成没有任何操作(我在那里进行空检查,因此这不是问题)。

那么,我该怎么办呢?如何将myFunction1与给定变量一起正确地传递给{{1}}作为参数?

2 个答案:

答案 0 :(得分:2)

花哨的新JavaScript环境和各种库(Prototype,Functional)提供了一个“绑定”API,给定一个函数(“f”)和一些参数,返回一个函数,当被调用时,将调用“f”您选择的this值和您选择的参数:

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

现在,请致电

bound();

将完全像

myFunction.call(something, v1, v2, myFunction3);

有时人们称之为“currying”,但实际上并不是真正的currying,因为在调用“bind()”时值都是绑定的。它仍然有用而且整洁。根据您想要获得的花哨程度,“bind()”非常容易实现;我建议查看Functional.js source code并从那里开始。 jQuery版本被称为$.proxy(),但它相对蹩脚(无法绑定参数)。

答案 1 :(得分:1)

如果您需要更加动态而不是将函数硬编码,那么如何将函数引用放在Array中作为第三个参数。然后每个调用可以.shift()一个关闭数组,直到没有剩下。

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
}