我想在目录中获取文件,打开它们,处理它们并写入结果。 我想用Promises做所有步骤异步
我头脑中的第一件事就是
read_dir('/tmp')
.then(function(files){
for(var i=0; i<files.length; i++){
read_file(files[i])
.then(function(file_data){
var processed_data = process_work_convert(file_data.data);
return {'filename': file_data.name, 'data': processed_data}
})
.then(function(file_data){
return write_file(file_data.filename, file_data.data);
})
.then(function(){
console.log('success');
})
}
})
但它看起来像标准的回调方式(回调地狱)
我可以使用Promise.all
但它会使我的代码同步
我想要一些魔法then_each
和catch_each
示例:
read_dir('/tmp')
.then_each(function(file){
return read_file(file);
})
.then_each(function(file_data){
var processed_data = process_work_convert(file_data.data);
return {'filename': file_data.name, 'data': processed_data}
})
.then_each(function(file_data){
return write_file(file_data.filename, file_data.data);
})
.then_each(function(){
console.log('success');
})
.catch_each(function(){
console.log('error');
});
这个功能是否存在?
或者你可能知道如何延伸Promise来实现这个目标吗?
或者可能有其他方法可以做到这一点?
答案 0 :(得分:2)
您正在寻找的代码是
read_dir('/tmp')
.then(function(files){
return Promise.all(files.map(function(file) {
return read_file(file)
.then(function(file_data) {
return write_file(file_data.name, process_work_convert(file_data.data));
});
}));
})
.then(function(){
console.log('success');
}, function(e){
console.log('error', e);
});
这里没有回调地狱,只是循环中的一些额外缩进。
如果您想减少回调次数,请查看即将发布的async
/await
syntax:
(async function() {
var files = await read_dir('/tmp');
await Promise.all(files.map(async function(file) {
var file_data = await read_file(file);
await write_file(file_data.name, process_work_convert(file_data.data));
}));
console.log('success');
}())
.catch(function(e){
console.log('error', e);
});
这个功能是否存在?
不,它不能(至少没有您试图避免的同步)。
答案 1 :(得分:0)
您可能会在此处找到relign。这是您使用relign parallelMap和ES6箭头函数编写的代码示例。
read_dir('/tmp')
.then(fileNames => relign.parallelMap(fileNames, fileName =>
read_file(fileName)
.then(file => ({ filename: file.name, data: process_work_convert(file.data) }))
.then(data => write_file(data.filename, data.data))))
.then(results => console.log(results))
.catch(err => console.error(err))