JavaScript обратные вызовы и функциональное программирование - PullRequest
12 голосов
/ 15 июня 2011

"Функциональное программирование описывает только операции, которые должны выполняться на входах в программы, без использования временных переменных для хранения промежуточных результатов."

Вопрос в том, как применить функциональное программирование и при этом использовать асинхронные модули, которые используют обратные вызовы. В некоторых случаях вам понадобился обратный вызов для доступа к переменной, которую представляет функция, вызывающая асинхронную ссылку, однако сигнатура обратного вызова уже определена.

пример:

function printSum(file,a){
     //var fs =....
     var c = a+b;
     fs.readFile(file,function cb(err,result){
          print(a+result);///but wait, I can't access a......
     });
}

Конечно, я могу получить доступ к a, но это будет против чисто функциональной парадигмы программирования

Ответы [ 3 ]

10 голосов
/ 15 июня 2011
fs.readFile(file, (function cb(err,result){
    print(this.a+result);
}).bind({a: a});

Просто введите context с переменными и областью действия в функцию, если необходимо.

Поскольку вы жалуетесь на API

fs.readFile(file, (function cb(a, err,result){
    print(a+result);
}).bind(null, a);

Это называется каррированием.Это намного больше FP.

1 голос
/ 15 июня 2011

Мне кажется, проблема в том, что вы неправильно понимаете, что они имеют в виду под использованием промежуточного значения (или они искажают его, я не читал ссылку).Учтите, что переменная в функциональном языке - это definition чего-то, и это определение не может измениться.Вполне допустимо использовать имена для значений / формул в функциональном программировании, если они не меняются.

function calculate(a,b,c) {
    // here we define an name to (a+b) so that we can use it later
    // there's nothing wrong with this "functionally", since we don't 
    // change it's definition later
    d = a + b;
    return c * d;
}

С другой стороны, следующее не будет нормально, функционально

function sum(listofvalues) {
    sum = 0;
    foreach value in listofvalues
        // this is bad, since we're re-defining "sum"
        sum += value;
    return sum
}

Для чего-то более близкого к тому, что было в вашем коде ... предположим, у вас есть вызов функции map that takes a list of things and a function to apply to a thing and returns a new list of things. It's perfectly acceptable to say:</p> <pre>function add_value(amount) { amount_to_incr = amount * 2; return function(amount, value) { // here we're using that "amount" value provided to us // the function returned will always return the same value for the same // input... its "referentially transparent" // and it uses the "intermediate" value of amount_to_incr... however, since // that value doesn't change, it's fine return amount_to_incr + value; } } map [1,2,3] add_value(2) ;// -> [3,4,5]

0 голосов
/ 26 апреля 2019
function printSum(file, a) {
     //var fs =....
     var c = a + b;
     fs.readFile(file, function cb(err, result, aa = a) {
          print(aa + result);
     });
}

С параметрами по умолчанию в настоящее время a может быть передано в обратный вызов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...