2016-11-19 5 views
2

Nach this snippet Ich versuche, eine Funktion zu schreiben, die durch ein Verzeichnis durchläuft, Verzeichnisse findet und Xml - Dateinamen aus diesen Verzeichnissen liest (ich weiß, dass die Ordnerstruktur immer die bleibt) gleich). Bis jetzt funktioniert meine Funktion wie erwartet, aber wenn ich versuche, die Rückkehr von der Funktion zu bekommen, bekomme ich nur Promise-Objekte.bluebird - Funktion gibt Versprechungsobjekte anstelle von tatsächlichen Daten zurück

Mein Code:

const Promise = require('bluebird'); 
const fs = Promise.promisifyAll(require('fs')); 
const path = require('path'); 

function getFileNames(rootPath) { 
    // Read content of path 
    return fs.readdirAsync(rootPath) 
    // For every file in path 
    .then(function(directories) { 
     // Filter out the directories 
     return directories.filter(function(file) { 
     return fs.statSync(path.join(rootPath, file)).isDirectory(); 
     }); 
    }) 
    // For every directory 
    .then(function(directories) { 
     return directories.map(function(directory) { 
     // Read file in the directory 
     return fs.readdirAsync(path.join(rootPath, directory)) 
      .filter(function(file) { 
      return path.extname(file) == '.XML'; 
      }) 
      .then(function(files) { 
      // Do something with the files 
      return files; 
      }); 
     }); 
    }); 
} 

getFileNames('./XML').then(function(files) { 
    console.log(files); 
}); 

Wenn ich console.log(files) innerhalb der letzten .then Funktion innerhalb getFileNames ich die tatsächlichen Arrays von Dateinamen in der Konsole. Aber wenn ich führen Sie den Code oben ich diese Ausgabe erhalten:

[ Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined }, 
    Promise { 
    _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined } ] 

Warum ist das passiert und wie man es beheben?

Antwort

2

in den Zeilen

.then(function(directories) { 
    return directories.map(function(directory) { 
    return fs.readdirAsync… 

Du ein Versprechen für eine Reihe von Versprechungen zu schaffen, und das ist genau das, was Sie in Ihrem letzten Protokoll sind immer. Anstatt eine Reihe von Versprechen der Rückkehr, müssen Sie ein Versprechen für eine Reihe von Werten zurückzukehren - und Promise.all ist genau das, was bedeutet das:

.then(function(directories) { 
    return Promise.all(directories.map(function(directory) { 
    return fs.readdirAsync(…) 
    … 
    })); 
}) 

jedoch in Drossel wäre es idiomatisch sein Promise.map(directories, function(…) { … }) zu verwenden oder sogar the map method (ähnlich wie Sie verwendet bereits .filter tat auf die Dateien in jedem Verzeichnis):

function getFileNames(rootPath) { 
    return fs.readdirAsync(rootPath) 
    .filter(function(file) { 
    return fs.statAsync(path.join(rootPath, file)).then(function(s) { 
     return s.isDirectory(); 
    }); 
    }) 
    .map(function(directory) { 
//^^^^ 
    return fs.readdirAsync(path.join(rootPath, directory)) 
    .filter(function(file) { 
     return path.extname(file) == '.XML'; 
    }) 
    .map(function(file) { 
     // Do something with every file 
     return file; 
    }); 
    }); 
} 
0

versuchen, dieses

return getFileNames('./XML').then(function(files) { 
    console.log(files); 
    return files; 
}); 
+0

stil immer die gleiche Ausgabe –

+0

@ MihaŠušteršič Ich bearbeite Antwort – stasovlas

0

Dieses Stück Code:

.then(function(directories) { 
    return directories.map(function(directory) { 
    return fs.readdirAsync(path.join(rootPath, directory)) 
    ... 

wird eine Reihe von Versprechungen an dem damaligen Rückruf zurückzukehren. Ein Array von Versprechungen zählt hier als unmittelbarer Wert, wird nicht als Promise eines Arrays angesehen. Um eine Reihe von Versprechen ein Versprechen eines Arrays zu konvertieren Sie Promise.all verwenden könnte, aber da Sie drossel verwenden, haben Sie eine bessere Option:

Alles, was Sie tun müssen, ist die Verwendung Promise.map:

.then(function(directories) { 
    return Promise.map(directories, function(directory) { 
    return fs.readdirAsync(path.join(rootPath, directory)) 
    ... 
0

es herausgefunden, war es ein .then zu sehr auf die zweite Funktion:

const Promise = require('bluebird'); 
const fs = Promise.promisifyAll(require('fs')); 
const path = require('path'); 

function getFileNames(rootPath) { 
    // Read content of path 
    return fs.readdirAsync(rootPath) 
     .then(function(content) { 
     return content.filter(function(file) { 
      return fs.statSync(path.join(rootPath, file)).isDirectory(); 
     }); 
     }) 
     // For every directory 
     .map(function(directory) { 
     // Read files in the directory 
     return fs.readdirAsync(path.join(rootPath, directory)) 
      .filter(function(file) { 
       return path.extname(file) == '.XML'; 
      }); 
     }); 
} 

getFileNames('./XML').then(function(files) { 
    console.log(files); 
}); 
Verwandte Themen