简体   繁体   中英

Promise chain split to perform multiple async tasks

I have a promise chain, at the end of which I want to perform parallel multiple waterfall operations.

fetchFiles(conf.src, conf.dest)
            .then(function(result) {
                return filterFiles(result, conf);
            })                                             // Here
            .catch(function(error) {
                console.log("Fail: " + error);
            });

At the here position I have an array of files. I want to foreach the result > open file > transform > save file

Not interested in the operations, just how to wire the operations together

I am trying do this in ES6

I think the following is what you're looking for. I used Bluebird only for the .delay method as a matter of convenience, to simulate the different tasks taking different lengths of time. The rest should run on ES2015 promises. You should be able to copy paste the whole thing, npm install bluebird and then run the code. You'll see that all the various tasks run in parallel and get completed asynchronously and out of order. Of course, for each file the tasks open , transform , save happen in sequence. (I hope nobody objects to my newly acquired distaste for semicolons)

'use strict'

var Promise = require('bluebird') // not needed for the actual solution

let inputFiles=[1,2,3,4,5,6,7,8,9,10,11,12]

Promise.resolve(inputFiles)  // this is your array of inputfiles
 .then(  files => {
    return files.map( file => {   // map each file to a promise sequence
      return openFile(file)
              .then(transformFile)
              .then(saveFile)
              .then(allDone)
    })
  })
 .catch( error => {
   console.error("Fail: " + error);
 })

// need to generate a promise for the opened file
function openFile(file) {
 return Promise.delay( file + '_opened',  Math.floor( Math.random() * 1000));
}

// these tasks don't need to return a promise, I'm just using
// Promise.delay as a convenience to simulate asynchrony
function transformFile(file) {
 console.log(`File ${file} opened ... Transforming`)
 return Promise.delay( file + '_transformed',  Math.floor( Math.random() * 1000));
}

function saveFile(file) {
 console.log(`File ${file} transformed ... Saving`)
 return Promise.delay( file + '_saved', Math.floor( Math.random() * 1000));
}

function allDone(file) {
 console.log(`File ${file} completed ... `)
}

The above will generate output like this:

File 6_opened opened ... Transforming
File 4_opened opened ... Transforming
File 7_opened opened ... Transforming
File 11_opened opened ... Transforming
File 7_opened_transformed transformed ... Saving
File 6_opened_transformed transformed ... Saving
File 3_opened opened ... Transforming
File 2_opened opened ... Transforming
File 11_opened_transformed transformed ... Saving
File 10_opened opened ... Transforming
File 4_opened_transformed transformed ... Saving
File 8_opened opened ... Transforming
File 12_opened opened ... Transforming
File 10_opened_transformed transformed ... Saving
File 5_opened opened ... Transforming
File 1_opened opened ... Transforming
File 3_opened_transformed transformed ... Saving
File 9_opened opened ... Transforming
File 2_opened_transformed transformed ... Saving
File 9_opened_transformed transformed ... Saving
File 4_opened_transformed_saved completed ...
File 11_opened_transformed_saved completed ...
File 6_opened_transformed_saved completed ...
File 7_opened_transformed_saved completed ...
File 8_opened_transformed transformed ... Saving
File 1_opened_transformed transformed ... Saving
File 12_opened_transformed transformed ... Saving
File 8_opened_transformed_saved completed ...
File 5_opened_transformed transformed ... Saving
File 9_opened_transformed_saved completed ...
File 10_opened_transformed_saved completed ...
File 5_opened_transformed_saved completed ...
File 3_opened_transformed_saved completed ...
File 2_opened_transformed_saved completed ...
File 12_opened_transformed_saved completed ...
File 1_opened_transformed_saved completed ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM