1

我是 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 回调之外.

我的逻辑缺少什么,我该如何更好地解决这个问题(即使这意味着重建每一件事)我担心我在设计和布局这些功能的方法中做错了什么,以及我如何处理它们之间的值.

非常感谢任何帮助!

4

2 回答 2

2

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

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

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

于 2013-08-14T21:15:06.987 回答
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
});

未经测试的 Gist 重构

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;
于 2013-08-14T21:26:36.123 回答