简体   繁体   中英

Event Loop async.waterfall node.js

I need to read the first and second files and write to the third file with async.waterfall. When I write to the third file, I can't get the data of 1, 2 files. How can this be implemented?

const unionFiles = (file1, file2, file3, cb) => {
  waterfall([
      fs.readFile(file1, 'utf-8', (err1, data1) => {
      callback(err1, data1);
    }),
    fs.readFile(file2, 'utf-8', (err2, data1, data2) => {
      cb(err2, data1, data2);
    }),
    fs.writeFile(file3, `${data1}${data2}`, (err3, data1, data2) => {
      cb(err3, data1, data2);
    })
  ]),
  cb(null);
}

As I can see in the documentation.

async.waterfall([
  function(callback) {
    callback(null, 'Task 1', 'Task 2');
  },
  function(arg1, arg2, callback) {
    // arg1 now equals 'Task 1' and arg2 now equals 'Task 2'
    let arg3 = arg1 + ' and ' + arg2;
    callback(null, arg3);
  },
  function(arg1, callback) {
    // arg1 now equals 'Task1 and Task2'
    arg1 += ' completed';
    callback(null, arg1);
  }
], function(err, result) {
  // result now equals to 'Task1 and Task2 completed'
  console.log(result);
});

Alternatively

It will run one function at a time and pass the result of the previous function to the next one.

async.waterfall([
  myFirstFunction,
  mySecondFunction,
  myLastFunction,
], function(err, result) {
  // result now equals 'Task1 and Task2 completed'
  console.log(result);
});

function myFirstFunction(callback) {
  callback(null, 'Task 1', 'Task 2');
}
function mySecondFunction(arg1, arg2, callback) {
  // arg1 now equals 'Task 1' and arg2 now equals 'Task 2'
  let arg3 = arg1 + ' and ' + arg2;
  callback(null, arg3);
}
function myLastFunction(arg1, callback) {
  // arg1 now equals 'Task1 and Task2'
  arg1 += ' completed';
  callback(null, arg1);
}

In Waterfall function, the result values are passed as arguments, in order, to the next task.

Also first arguments in callback is reserved for Error. So when this line is executed

callback(err1, data1);

That means an error is thrown. So next function will not be called.

Have updated your code. Final code could something like this:

const unionFiles = (file1, file2, file3, cb) => {
const params:any = {};
        params.file1 = file1;
        params.file2 = file2;
        params.file3= file3;


let tasks:Function[]= [];
  tasks.push(async.constant(params))  
  //Tasks will be executed in order
  tasks.push(readFile1, readFile2,writeFile);
  async.waterfall(
  tasks,
  function(err, result){
      // Handle Error here
  }),cb(null);
}

    function readFileF1(params,callback){
      fs.readFile(params.file1, 'utf-8', (err1, data1) => {
      if(err1)
       callback(err1);
      callback(null, params,data1);
    });
    
    }
    
    function readFileF2(params,data1,callback){
      fs.readFile(params.file2, 'utf-8', (err2, data2) => {
      if(err1)
       callback(err2);
      callback(null, params,data1+data2);
    });
    
    }
    
    function writeFile(params,combinedData,callback){
      fs.writeFile(prams.file3, 'utf-8', (err2, data1) => {
      if(err1)
       callback(err2);
      callback(null);
    });
    
    }

The other method of achieving the same result is to use a promise library like BlueBird:

var fs = require('fs');
var readFile = Promise.promisify(fs.readFile);
var writeFile = Promise.promisify(fs.writeFile);
var Promise = require('bluebird');

var promiseArray = [readFile('file1.txt'), readFile('file2.txt')];

Promise.all(promiseArray).then((dataArray)=>{
     var data = '';
     for(var i=0;i<dataArray.length;i++){
          data += dataArray[i];
     }
     return writeFile('file3.txt', data);
});

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