Domanda

Funzione dirList() dovrebbe tornare la matrice di cartelle all'interno della directory defindita.Non riesco a capire come restituire la variabile dirList solo dopo l'esecuzione della funzione isDir() per ogni file.

Immagino che dovrei usare Q.all(), ma non so dove dovrei metterlo: - (

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);
    }
);
.

È stato utile?

Soluzione

Il problema che stai vivendo è che Array.prototype.filter non conosce le promesse, quindi vede solo un valore di verità (in realtà un oggetto promessa) e aggiunge il file all'elenco di uscita.Segue un modo per risolvere il problema (potrebbe esserci un modo "pulito" possibile con qualcosa come 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);
    });
.

Altri suggerimenti

Il metodo ARRAY filter non funziona con un risultato promessa asincrono, si aspetta che un booleano venga restituito sincrono in modo sincrono.

Suggerirei di utilizzare una funzione che controlla se un determinato percorso è una directory e restituisce una promessa per il file se è stato il caso e una promessa per niente.Quindi puoi aspettare con Q.all() per i risultati di questo per ogni percorso, e poi per unirti ai risultati "positivi" insieme, omettendo i "negativi":

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;
        });
    });
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top