如何在没有承诺地狱的情况下运行异步Promises?

时间:2016-11-08 14:58:19

标签: javascript asynchronous promise

我想在目录中获取文件,打开它们,处理它们并写入结果。 我想用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_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来实现这个目标吗?

或者可能有其他方法可以做到这一点?

2 个答案:

答案 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))
相关问题