سؤال

لدي حلقة، وداخلها يتم تعيين متغير مع VAR. أيضا داخل الحلقة، يتم استدعاء الطريقة التي تتطلب رد اتصال. داخل وظيفة رد الاتصال، أستخدم المتغير من الحلقة. كنت أتوقع أن تكون القيمة، داخل وظيفة رد الاتصال، ستكون هي نفسها كما كانت خارج رد الاتصال أثناء هذا التكرار للحلقة. ومع ذلك، يبدو دائما أن تكون القيمة من الاخير التكرار للحلقة.

هل أنا أسيء الفهم نطاق في جافا سكريبت، أم أن هناك شيئا آخر خطأ؟

البرنامج المعني هنا هو تطبيق 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