2013-08-05 4 views
2

Можно ли вызывать неназванную функцию обратного вызова асинхронной функции рекурсивно внутри этой функции?Можно ли назвать это «рекурсивно» в JavaScript?

Это псевдокод, но идея состоит в том, что я хочу повторно вызвать неудавшийся запрос HTTP.

function(err, res) { //parent callback 
    request.get(URL, function(err, res) { 
     if (err == 209) { //call the nameless parent function but how? 
     } 
    }); 
} 
+0

Если анонимная функция назначена переменной, то да, вы можете вызвать ее, обратившись к переменной. –

+1

Если это анонимно, и у вас нет ссылки на него, тогда это невозможно. – Bergi

+0

Кто-то должен отправить ответ y-combinator. – Pointy

ответ

1

Я не думаю, что есть способ сделать это с помощью безымянной функции, но почему бы не назвать ее именем?

function doRequest(err, res) { 
    request.get(URL, function(err, res) { 
     if (err==209) { 
      doRequest(); 
     } 
    }); 
} 

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

setTimeout(function doRequest(err, res) { ... }, 200); 

Или, если вы звоните непосредственно вы можете создать его внутри IIFE, чтобы избежать утечки его имя в текущей области видимости.

+2

Будут предупреждены, более старые версии функций conf confate * выражений * и функций *. '(function doRequest (err, res) {...})' фактически определяет 'doRequest' в глобальной области. – cHao

+2

@cHao: Не в глобальном масштабе, но он создает второй объект функции. Подробнее см. Http://kangax.github.io/nfe/ (и винт IE, imho) – Bergi

+0

Спасибо! Я использую backend node.js, поэтому IE не проблема. – metalaureate

1

Вы можете создать замыкание и ссылки на внутреннюю функцию, Вы заявляете, как:

var obj = { 
    a: (function() { 
     var func = function() { //parent callback 
      request.get(URL, function(err, res) { 
       if (err == 209) { 
        func(); 
       } 
      }); 
     }; 
     return func; 
    }()) 
}; 

Упрощенная DEMO:http://jsfiddle.net/UqMhK/

Вы бы затем вызвать obj.a(); как нормальный.

Это позволяет сохранить исходную структуру и не называть анонимную функцию, но выполняет то, что вам кажется нужным.

+0

Ничего себе, так много разных способов сделать это. Спасибо! – metalaureate

1

Есть несколько способов сделать это, но я думаю, что лучший способ для кода, публикуемыми должен выглядеть примерно так:

var stillALambda = function thatFunction(err, res) { 
    request.get(URL, function(err, res) { 
    if (err == 209) thatFunction(); 
    }); 
}; 

Функция выше еще лямбда, но теперь внешняя область действия содержит ссылку на себя в thatFunction. Благодаря всемогущей способности закрытия, это может быть использовано и внутри внутренней функции.

+0

Спасибо за этот подход. – metalaureate

Смежные вопросы