2016-11-08 80 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))