Frage

Funktion dirList() sollte eine Reihe von Ordnern im definierten Verzeichnis zurückgeben.Ich kann nicht verstehen, wie zurückkommen dirList Variable erst nach der Funktion isDir() wird für jede Datei ausgeführt.

Ich denke, das sollte ich verwenden Q.all(), aber ich weiß nicht, wo ich es hinstellen soll :-(

var fs = require('fs'),
    Q = require('q'),
    readdir = Q.denodeify(fs.readdir);

function isDir(path) {
    return Q.nfcall(fs.stat, __dirname + path)
        .then(function (stats) {
            if (stats.isDirectory()) {
                return true;
            } else {
                return false;
            }
        });
}

function dirList(path) {
    return readdir(__dirname + path).then(function (files) {
        var dirList = files.filter(function (file) {
                return isDir(path + file).then(function (isDir) {
                    return isDir;
                });
            });
        return dirList;
    });
}

dirList('/').done(
    function (data) {
        console.log(data);
    },
    function (err) {
        console.log(err);
    }
);
War es hilfreich?

Lösung

Das Problem, das Sie haben, ist folgendes Array.prototype.filter kennt keine Versprechungen, sieht also nur einen wahren Wert (eigentlich ein Versprechungsobjekt) und fügt die Datei der Ausgabeliste hinzu.Eine Möglichkeit, das Problem zu lösen, ist folgende (möglicherweise gibt es eine „sauberere“ Möglichkeit mit etwas wie AsyncJS):

'use strict';

var fs = require('fs'),
    Q = require('q'),
    readdir = Q.denodeify(fs.readdir);

function isDir(path) {
    return Q.nfcall(fs.stat, __dirname + path)
        .then(function (stats) {
            return stats.isDirectory();
        });
}

function dirList(path) {
    return readdir(__dirname + path).then(function (files) {
        // here we map the list of files to an array or promises for determining
        // if they are directories
        var dirPromises = files.map(function (file) {
            return isDir(path + file);
        });
        // here is the Q.all you need
        return Q.all(dirPromises)
            // here we translate the array or directory true/false values back to file names
            .then(function(isDir) {
                return files.filter(function(file, index) { return isDir[index]; });
            });
    });
}

dirList('/').done(
    function (data) {
        console.log(data);
    },
    function (err) {
        console.log(err);
    });

Andere Tipps

Das Array filter Die Methode funktioniert nicht mit einem asynchronen Promise-Ergebnis, sie erwartet, dass ein boolescher Wert synchron zurückgegeben wird.

Ich würde vorschlagen, eine Funktion zu verwenden, die prüft, ob ein bestimmter Pfad ein Verzeichnis ist, und in diesem Fall ein Versprechen für die Datei zurückgibt, andernfalls ein Versprechen für nichts.Sie können dann mit warten Q.all() um die Ergebnisse für jeden Pfad zu ermitteln und dann die „positiven“ Ergebnisse zusammenzufügen und die „negativen“ wegzulassen:

function isDir(path) {
    return Q.nfcall(fs.stat, __dirname + path).invoke("isDirectory");
}

function dirList(path) {
    return readdir(__dirname + path).then(function (files) {
        var maybeDirPromiseList = files.map(function (file) {
            return isDir(path + file).then(function (isDir) {
                return isDir ? [file] : []; // Maybe represented as list
            });
        });
        var maybeDirsPromise = Q.all(maybeDirPromiseList);
        return maybeDirsPromise.then(function(maybeDirList) {
             return [].concat.apply([], maybeDirList);
             // is equivalent to:
             var dirList = [];
             for (var i=0; i<maybeDirList.length; i++)
                 if (maybeDirList[i] && maybeDirList[i].length > 0)
                     dirList.push(maybeDirList[i][0]);
             return dirList;
        });
    });
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top