[英]return after all promises in Array.forEach block has been resolved
我正在嘗試一個簡單的示例中的node6-js中的es6-promisify模塊,該示例類似於es6-promisify的npm頁面上的示例 。 但是我想使用forEach循環來檢查條目的統計信息,如果它們是目錄,則將它們推到單獨的數組中:
var fs=require('fs');
var promisify=require('es6-promisify');
var path='../test_folder/';
function listSubfolderNamesSync(fpath){
var arrayOfFolders=[];
var array=fs.readdirSync(fpath);
array.forEach(function(element,index,array){
var stat=promisify(fs.stat);
stat(path+element).then(function(stats){
if (stats.isDirectory()){
arrayOfFolders.push(element);
console.log('pushed');
}
})
});
return arrayOfFolders;
}
console.log(listSubfolderNamesSync(path));
使用2個子文件夾,輸出為:
[]
pushed
pushed
我知道為什么我的代碼無法按我希望的那樣工作,但是我無法弄清楚如何優雅地解決此問題。 我已經看到帶有Promise.all()
代碼示例以及Promise.all()
的使用, Array.map()
具有一個promise數組,並等待它們全部解析后才能在鏈中前進。 我看到的問題是,我不能/不想在每次檢查統計信息時都顯式創建一個Promise.all(array)
,並將這些Promise.all(array)
放入數組中以使用Promise.all(array)
。 我感覺該解決方案將需要一種變通辦法,並且將大大降低代碼的可讀性。 也許最好在forEach循環中使用它,這是我想要嘗試承諾之前的工作代碼:
if(fs.statSync(path+element).isDirectory()){
arrayOfFolders.push(element);
}
可能是由於我缺乏編程經驗,但似乎混合承諾,回調和同步代碼並不像書中那樣簡單?
由於stat()
返回一個promise,所以您的listSubfolderNamesSync()
函數也必須將其listSubfolderNamesAsync()
。 除非可以使用stat()
的同步替代方法,否則這是不可避免的。
在listSubfolderNamesAsync()
內部,您需要將fs.readdirSync()
返回的數組映射到一個fs.readdirSync()
數組,然后使用Promise.all()
將這些Promise.all()
(及其提供的數據Promise.all()
聚合到一個Promise.all()
。
var fs = require('fs');
var promisify = require('es6-promisify');
var stat = promisify(fs.stat);
var path = '../test_folder/';
function listSubfolderNamesAsync(fpath) {
var promises = fs.readdirSync(fpath).map(function(element) {
return stat(path + element).then(function(stats) {
return stats.isDirectory() ? element : null;
});
});
return Promise.all(promises).then(function(results) {
return results.filter(function(res) {
return res !== null;
});
});
}
現在使用.then()
處理結果:
listSubfolderNamesAsync(path).then(function(folders) {
console.log(folders);
});
使用更通用的函數返回文件夾和文件的單獨列表不會對性能造成很大的影響。 您可以這樣寫:
function listSubElementsAsync(fpath) {
var promises = fs.readdirSync(fpath).map(function(element) {
return stat(path + element).then(function(stats) {
var type = stats.isDirectory() ? 'folder' : 'file';
return {type:type, element:element};
});
});
return Promise.all(promises).then(function(results) {
var files = results.filter(obj => obj.type === 'file').map(obj => obj.element);
var folders = results.filter(obj => obj.type === 'folder').map(obj => obj.element);
return {files:files, folders:folders};
});
}
listSubElementsAsync(path).then(function(list) {
console.log(list.files);
console.log(list.folders);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.