1

私はJavascriptの初心者であり、経験豊富なプログラマーであり、アプリケーションの構築中に使用およびアプローチするのに最適な構造のパターンと設計の概念を把握するのに非常に苦労しています。いくつかの分野は私にとってまったく新しいもので、そのうちの 1 つは Javascript のスコープとクロージャをマスターすることです。

ですから、皆さんのためにこれをできるだけきれいにするために、この投稿にコードのサンプルを添付しました。誰かが私のロジックを配置し、再考して正しく考えるためのガイドラインを与えてくれることを願っています.

私が投稿しているコードは、ディレクトリをスキャンし、それらのディレクトリでいくつかの条件を実行し、結果をマップとして返​​します。配列を別のライブラリに移動します (投稿されていません)。表示されているコードは、現在の「テスト」条件です。適当にコメントしました。

要点: 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 <----      
}

十分なアイスブレーキングです。私の最大の問題:

何をやってもかなり小さいスコープ(巻き上げ)とクロージャーが邪魔。どうすればいいのかわからないので、現在ゲッターもセッターも使用していません。私の論理は完全に間違っていますか、それともかなり基本的なものを見逃していますか?

コードでは、scan() プロトタイプ関数が、true/false 値または配列のいずれかを返す各関数「ヘルパー」に対して 1 回の呼び出しを行うことがわかります。

メインの scan() 関数に値を返すだけでこれらを操作できますが、人生のために fs.readdir() 関数からこれらの値を取得してスコープ外、たとえば ioResponse コールバックの外に返すことはできません。 .

私のロジックに欠けているものは何ですか、これにどのようにアプローチすればよいでしょうか (すべてを再構築することを意味する場合でも)、これらの関数を設計およびレイアウトするアプローチで何かひどく間違ったことをしているのではないかと心配しています。 .

どんな支援も大歓迎です!

4

2 に答える 2

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 に答える