문제

for 루프가 있고 그 안에는 변수가 var로 할당됩니다. 또한 루프 내부에서 콜백이 필요한 메소드가 호출됩니다. 콜백 함수 내에서 루프에서 변수를 사용하고 있습니다. 콜백 함수 내부에서 값이 루프 반복 중에 콜백 외부에있는 것과 동일 할 것으로 기대합니다. 그러나 그것은 항상의 가치 인 것 같습니다. 마지막 루프 반복.

JavaScript에서 범위를 오해하고 있습니까, 아니면 다른 잘못된 것이 있습니까?

여기에 문제가있는 프로그램은 Node.js 앱으로 변경에 대한 작업 디렉토리를 모니터링하고 서버가 찾을 때 서버를 다시 시작합니다. 호기심에 대한 모든 코드를 포함 시키지만 중요한 비트는 parse_file_list 기능입니다.

var posix = require('posix');
var sys = require('sys');
var server;
var child_js_file = process.ARGV[2];
var current_dir = __filename.split('/');
current_dir = current_dir.slice(0, current_dir.length-1).join('/');

var start_server = function(){
    server = process.createChildProcess('node', [child_js_file]);
    server.addListener("output", function(data){sys.puts(data);});
};

var restart_server = function(){
    sys.puts('change discovered, restarting server');
    server.close();
    start_server();
};

var parse_file_list = function(dir, files){
    for (var i=0;i<files.length;i++){
        var file = dir+'/'+files[i];
        sys.puts('file assigned: '+file);
        posix.stat(file).addCallback(function(stats){
            sys.puts('stats returned: '+file);
            if (stats.isDirectory())
                posix.readdir(file).addCallback(function(files){
                    parse_file_list(file, files);
                });
            else if (stats.isFile())
                process.watchFile(file, restart_server);
        });
    }
};

posix.readdir(current_dir).addCallback(function(files){
    parse_file_list(current_dir, files);
});

start_server();

이것의 출력은 다음과 같습니다.

file assigned: /home/defrex/code/node/ejs.js
file assigned: /home/defrex/code/node/templates
file assigned: /home/defrex/code/node/web
file assigned: /home/defrex/code/node/server.js
file assigned: /home/defrex/code/node/settings.js
file assigned: /home/defrex/code/node/apps
file assigned: /home/defrex/code/node/dev_server.js
file assigned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js
stats returned: /home/defrex/code/node/main_urls.js

미래의 사람들을 위해 : node.devserver.js

도움이 되었습니까?

해결책

이것은 완벽하게 정상적인 행동입니다. 콜백은 나중에 (비동기 적으로) 실행되지만 여전히 범위를 참조합니다. ~을 위한 루프가 실행되었습니다. 모든 콜백 참조 파일 따라서 마지막으로 설정된 값이 있습니다.

당신이하고 싶은 것은 새로운 함수 범위를 만들고 현재 값을 할당하는 것입니다. 파일 로컬 변수에 그리고 해당 범위 내부에서 콜백을 만듭니다.

    for (var i=0;i<files.length;i++){
        var file = dir+'/'+files[i];
        (function() {
            var file_on_callback = file;
            sys.puts('file assigned: '+ file_on_callback);
            posix.stat(file_on_callback).addCallback(function(stats){
                sys.puts('stats returned: '+ file_on_callback);
                if (stats.isDirectory())
                    posix.readdir(file_on_callback).addCallback(function(files){
                        parse_file_list(file_on_callback, files);
                    });
                else if (stats.isFile())
                    process.watchFile(file_on_callback, restart_server);
            });
        })(); // This creates and executes a new function with its own scope.
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top