setTimeout () для рекурсивной функции внутри функции, вызывающей себя - PullRequest
5 голосов
/ 11 января 2012

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

(function(window, document, undefined) {
  staffHappens();
  var initMyLib = function() {
    if (typeof(myLib) == 'undefined') {
      setTimeout("initMyLib()", 50);
    } else {
      useMyLib();
    }
  }
  moreStaffHappens();
  initMyLib(); //-> initMyLib is undefined
})(this, document);

Как может возникнуть эта ошибка?Должен ли initMyLib находиться в области действия включающей (самовывоз) функции?

Ответы [ 3 ]

11 голосов
/ 11 января 2012

изменить setTimeout("initMyLib()", 50); на setTimeout(initMyLib, 50);

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


Демо на http://jsfiddle.net/gaby/zVr7L/

2 голосов
/ 28 февраля 2016

Попробуйте прочитать этот ответ для некоторых подсказок: рекурсивная функция против setInterval против setTimeout javascript

Это пример кода из этого ответа:

/*
this will obviously crash... and all recursion is at risk of running out of call stack and breaking your page...

function recursion(c){
    c = c || 0;
    console.log(c++);
    recursion(c);
}
recursion();

*/

// add a setTimeout to reset the call stack and it will run "forever" without breaking your page!
// use chrome's heap snapshot tool to prove it to yourself.  :)

function recursion(c){
    setTimeout(function(c){
        c = c || 0;
        console.log(c++);
        recursion(c);
    },0,c);
}

recursion();

// another approach is to use event handlers, but that ultimately uses more code and more resources
1 голос
/ 11 января 2012

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

(function() {
    if(typeof(myLib) == 'undefined')
        setTimeout(arguments.callee, 50);
    else
        // loaded
})()
...