在javascript中返回不同范围之间的值

时间:2013-08-14 21:10:07

标签: javascript node.js scope closures

我是Javascript的新手,也是经验丰富的程序员,在构建应用程序时,我正在努力抓住模式和设计最佳结构的概念。 一些领域对我来说很新,一个是掌握Javascript的范围和结束。

所以为了让你们尽可能干净,我已经在这篇文章中附上了一些代码示例,希望有人可以把我的逻辑放在一边,给我一个重新思考和思考的准则。

我发布的代码是一个非常简单的文件系统/帮助程序库(Node.js,express)的一部分,用于扫描目录,在这些目录上运行一些条件并将结果作为映射返回数组到另一个库(未发布)的维度。您看到的代码是我当前的“测试”条件。我公平评论过它。

要点:https://gist.github.com/jimmiehansson/6235613(全景或代码/图书馆)

示例代码块(返回值时出现问题)

ApiFS.prototype.scan = function(){          
    var self = this;
    var b;
    fs.readdir(stgs.fsPath, function(err,folders){      
        if(folders.length<1) { console.log(errLog.fsEmpty); return; }       
        rslt = self.walk(folders);          
        rslt.forEach(function(itm){
            if(!self.exclusion(rslt)){ b=self.loader(stgs.fsPath,itm); }        
        });                     
    }, ioResponse);
    console.log(b); // undefined <----      
}

足够破冰。我最大的问题是:

无论我做什么,范围(吊装)和封闭都相当小,妨碍了我。我目前没有使用getter或setter,因为我根本不知道应该怎么做?我的逻辑是完全关闭的,还是我错过了一些相当基本的东西?

在代码中,您将看到scan()原型函数对每个返回true / false值或数组的函数“helper”进行单次调用。

我可以通过将值返回到主scan()函数来处理这些问题,但是我不能为了生命而从fs.readdir()函数中获取这些值以返回到范围之外,例如外部ioResponse回调。

我缺少什么逻辑,我怎样才能更好地解决这个问题(即使它意味着重建每一件事)我担心我在设计和布局这些函数的方法上做了一些非常错误的事情,以及我如何处理这些函数在他们之间。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

这与范围无关,而是与时间有关。 readdir是异步的。它将请求发送到文件系统,然后让前一个函数继续运行。

console.log(b);b=self.loader()之前执行

如果您想处理来自回调函数的数据,您需要在回调中执行工作。

答案 1 :(得分:0)

昆汀是对的。你肯定必须习惯节点程序的异步性质。为了说清楚,这应该像你期望的那样工作。

ApiFS.prototype.scan = function(callback){          
    var self = this;
    var b;
    fs.readdir(stgs.fsPath, function(err, folders) {      
        if(folders.length<1) { console.log(errLog.fsEmpty); return; }

        var results = [];
        async.each(folders, function(folder) {
            if(!self.exclusion(folder)) { 
                results.push(self.loader(stgs.fsPath, itm)); 
            }            
        }, function() {});

        if(typeof(callback) == "function") {
            callback(b);
        }
    });
}

ApiFS.scan(function(files) {
    // Do something with files
});

未经考验重构您的要点

var fs = require('fs'),
    async = require('async'),
    _ = require('underscore'),
    path = require('path');

ApiFS = function(options){
    errLog = [];
    errLog.fsEmpty = "No existing directories or empty, cannot continue."; 
}

ApiFS.prototype.scan = function(callback) {          
    var self = this,
        results = {};
    fs.readdir(options.fsPath, function(err, folders) {
        if(folders.length<1) return callback(errLog.fsEmpty);       
        async.forEach(folders, function(folder) {
            if(!self.exclude(folder)) {
                self.loadFiles(folder, function(err, files) {
                    results[folder] = files;
                });
        }, function(err) {
            callback(err, results);
        });                     
    });     
}

ApiFS.prototype.exclude = function(folder){       
    if(options.exclude.length === 0){
        return false;
    }

    return _.contains(options.exclude, folder);
}

ApiFS.prototype.loadFiles = function(folder, callback) { 
    fs.readdir(path.join(options.fsPath, folder), function(err, files) {
        callback(err, files);
    });
};

exports = module.exports = ApiFS;