2016-11-08 48 views
0

我想要在目录中获取文件,打开它们,处理它们并写入结果。 我想要做的所有步骤异步与承诺如何在没有承诺的情况下运行异步承诺?

第一件事情来到我的头是

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_eachcatch_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

您的目标是生成文件夹资源管理器吗?你有没有考虑过使用递归方法?有关承诺的更多文档,您还可以查看Mozilla文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – Cr3aHal0

+0

不,不是文件夹浏览器。我想从文件夹中获取所有日志文件并将其转换为其他格式。 –

+3

“*我可以使用Promise.all,但它会使我的代码同步*” - 等什么?编号 – Bergi

回答

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

,这种功能存在吗?

不,它不能(至少没有你试图避免的同步)。

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))