Frage

Ich habe eine for-Schleife, und im Inneren eine Variable mit var zugeordnet. Auch innerhalb der Schleife wird ein Verfahren genannt, welches einen Rückruf erfordert. Innerhalb der Callback-Funktion verwende ich die Variable aus der Schleife. Ich würde zu erwarten, dass es Wert ist, innerhalb der Callback-Funktion, wäre das gleiche, wie es außerhalb des Rückrufs während dieser Iteration der Schleife war. Allerdings scheint es immer der Wert aus der letzten Iteration der Schleife zu sein.

Bin ich Missverständnis Umfang in JavaScript oder es ist etwas anderes falsch?

Das Programm in Frage hier ist eine node.js-Anwendung, die ein Arbeitsverzeichnis für Änderungen überwachen und den Server neu starten, wenn es eine findet. Ich werde den gesamten Code für die Neugierigen sind, aber die wichtige Bit ist die parse_file_list Funktion.

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();

Die Ausgabe von diesen ist:

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

Für diejenigen, die aus der Zukunft: node.devserver.js

War es hilfreich?

Lösung

Das ist völlig normal. Ihre Rückrufe werden zu einem späteren Zeitpunkt (asynchron) ausgeführt, sondern verweisen immer noch den Umfang der für Schleife ausgeführt wurde. All Callback-Verweis auf Datei wird daher den letzten Wert war auf.

Was möchten Sie tun, ist eine neue Funktion Bereich erstellen, um den aktuellen Wert von Datei auf eine lokale Variable zuweisen und erstellen den Rückruf innerhalb dieses Bereichs.

    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.
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top