Cyber Lis Cyber Lis - 27 days ago 9
Javascript Question

How do i run async Promises without promise hell?

I want get files in directory, open them, process them, and write result.
I want do all step async with Promises

First thing came to my head was

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


But it looks like standard callback way (callback hell)

I can use
Promise.all
but it will make my code synchronous

I want some magic
then_each
and
catch_each


example:

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


Does this function exist ?

Or may be you know how extend Promise to achive this?

Or may be there is some othe way to do this?

Answer

The code you are looking for is

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

There is no callback hell here, just some extra indentation from the looping.

If you want to do with less callbacks, have a look at the upcoming 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);
});

Does this function exist?

No, it cannot (at least without the synchronisation that you are trying to avoid).

Comments