Question

Fonction dirList() devrait renvoyer un tableau de dossiers dans le répertoire défini.Je ne comprends pas comment revenir dirList variable seulement après la fonction isDir() est exécuté pour chaque fichier.

Je suppose que je devrais utiliser Q.all(), mais je ne sais pas où le mettre :-(

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);
    }
);
Était-ce utile?

La solution

Le problème que vous rencontrez est que Array.prototype.filter ne connaît pas les promesses, il voit donc simplement une valeur véridique (en fait un objet de promesse) et ajoute le fichier à la liste de sortie.Une façon de résoudre le problème suit (il peut y avoir une manière "plus propre" possible avec quelque chose comme 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);
    });

Autres conseils

Le tableau filter La méthode ne fonctionne pas avec un résultat de promesse asynchrone, elle s'attend à ce qu'un booléen soit renvoyé de manière synchrone.

Je suggérerais d'utiliser une fonction qui vérifie si un chemin donné est un répertoire et renvoie une promesse pour le fichier si tel était le cas et une promesse pour rien sinon.Vous pouvez alors attendre avec Q.all() pour les résultats de ceci pour chaque chemin, puis de joindre les résultats "positifs", en omettant les "négatifs":

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;
        });
    });
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top