Как передать функцию с нестатическими аргументами другой функции в качестве переменной в JavaScript? - PullRequest
2 голосов
/ 17 января 2011

Вот пример кода:

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 в качестве аргумента?

Ответы [ 2 ]

2 голосов
/ 17 января 2011

Представьте себе новые среды JavaScript и различные библиотеки (Prototype, Functional), которые предоставляют API "связывания", который, учитывая функцию ("f") и некоторые параметры, возвращает функцию, которая при вызове будет вызывать "f" выбранное вами значение this и выбранные вами параметры:

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

Теперь звоню

bound();

будет в точности как

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

Иногда люди называют это «каррированием», но на самом деле это не совсем карри, потому что все значения связаны в то время, когда вызывается «bind ()». Тем не менее, это полезно и аккуратно. В зависимости от того, насколько вы хотите, «bind ()» довольно легко реализовать; Я рекомендую посмотреть исходный код Functional.js и перейти оттуда. Версия jQuery называется $.proxy(), но она относительно хромая (не может связывать аргументы).

1 голос
/ 17 января 2011

Если вам нужно, чтобы это было немного более динамичным, вместо того, чтобы жестко кодировать функции, как насчет размещения ссылок на функции в массиве в качестве 3-го аргумента. Тогда каждый вызов может .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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...