在 Array.forEach 块中的所有承诺都已解决后返回
return after all promises in Array.forEach block has been resolved
我正在一个简单的例子中尝试nodejs中的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()
的代码示例和Array.map()
的使用,以拥有一系列承诺,并等待所有这些承诺解决,然后再在链中前进。我看到的问题是,我不能/不想在每次检查统计数据并将这些承诺放入数组中以使用 Promise.all(array)
时显式创建一个承诺。我觉得该解决方案需要相当多的解决方法,并且会大大降低代码的可读性。也许最好在forEach循环中使用它,这是我在我想尝试承诺之前的工作代码:
if(fs.statSync(path+element).isDirectory()){
arrayOfFolders.push(element);
}
可能是因为我缺乏编程经验,但似乎混合承诺、回调和同步代码并不像书上写的那么简单?
> 由于stat()
返回一个承诺,因此您的listSubfolderNamesSync()
函数也必须返回,使其listSubfolderNamesAsync()
。除非有stat()
的同步替代方案,否则这是不可避免的。
在 listSubfolderNamesAsync()
中,您需要将 fs.readdirSync()
返回的数组映射到一个承诺数组,然后使用 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);
});
- 简单的ES6承诺问题-交换解决和拒绝参数
- RxJS等待承诺解决
- 如何在解决承诺之前和之后验证值
- AngularJS-我怎么知道何时解决了对父控制器的承诺
- 在我的案例中,如何解决我的承诺问题
- 所有承诺解决后返回
- $.当承诺解决得太早时
- 如果你用另一个承诺解决一个承诺会发生什么
- 基于另一个承诺解决承诺
- 承诺解决不了问题
- 如何知道什么时候所有的承诺都被拒绝了,或者用基本的js承诺解决了
- Ember RSVP承诺解决firefox插件端口消息传递方案无法解决的模型
- 客户端等待服务器承诺解决
- while(true)循环中的承诺/等待承诺解决
- 推迟承诺解决
- 用承诺解决jQuery延迟
- 等待多个单独的承诺解决
- EmberJS - 在承诺解决后调用超级操作
- 如何为另一个承诺解决一个承诺
- 为什么我的承诺散列在传递的承诺解决之前就解决了?