使用async.parallel和async / wait的Node.js有没有更好的办法做到这一点

时间:2019-01-25 07:09:50

标签: node.js async-await async.js

这是一种更好的方法,在下面的代码有效的情况下,我想做的是

  1. 读取schedule.json文件
  2. 处理每个主要时间表 同步
  3. 子计划可以并行运行
    const async = require('async');
    const schedule = {
      "scheduleA": {
        "JobA":"a.bat 1000",
        "JobB":"b.bat 800"
      },
      "scheduleB":{
        "JobC":"c.js 600"
      },
      "scheduleC":{
        "JobD":"d.js 400"
      },
    "scheduleD": {
        "JobE":"e.bat 200",
        "JobF":"f.js 0"
      }  
    };

    var wait = (job, sleepTime) =>{
      return new Promise(function(resolve, reject){

        setTimeout( ()=>{
          resolve(job+' - Completed');
        }, sleepTime);

      });
    }

    var executeSchedule = (sched, jobs) =>{
      return new Promise(function(resolve, reject) {  
        console.log('Processing Schedule : '+sched);
        let stack = [];
        let keys1 = Object.keys(jobs);
        for(let i=0; i<keys1.length; i++){
          let temp = jobs[keys1[i]].split(' ');
          console.log('executeSchedule : '+temp);
          stack.push(function(callback){ callback(null,wait(temp[0], temp[1])) });
        }

        async.parallel(stack,function(err,result){
        if (err) {
            console.log(err);
            reject(err);
        }
          console.log("Before Results are: " + result);
          Promise.all(result).then( resp =>{
            console.log("After Results are: " + resp);
            resolve(resp);
          });

        });

      });
    }

    const start = ()=>{
      return new Promise(async function(resolve, reject) {  
        let results = [];
        let keys1 = Object.keys(schedule);
        console.log(keys1);
        for(let i=0; i<keys1.length; i++){
          let sr = await executeSchedule(keys1[i], schedule[keys1[i]]);
          results.push(sr);
        }
        resolve(results);
      });
    }


    start().then( resp =>{
      console.log('Response : '+JSON.stringify(resp, null, 2));
    }).catch( err => {
      console.log('Error : '+err);
    });

最终将用child_process / spawn / exec功能替换wait(),这将触发Windows中的.bat和.js程序。

我想知道的是

  1. 有没有一种更好的方法来编写程序,最初想到async.series来处理主调度程序(当前在start()中使用了async / await)。
  2. 当前在executeSchedule中,我正在使用async.parallel,也可以使用async.map。但是我想知道的是,在不使用异步库(或异步)的情况下,有没有更简单的更好的本机nodejs方式本身更适合。

1 个答案:

答案 0 :(得分:1)

您可以将其与promise链一起玩。

要进行序列化,仅需要实现“下一个”功能或使用可迭代项,对于Parallel,您只需使用Promise.all

请注意注释中所说的“显式Promise构造反模式”,因为它会增加巨大的性能开销。

这是一个工作示例,从以下位置开始:

const schedule = {
  "scheduleA": {
    "JobA": "a.bat 1000",
    "JobB": "b.bat 800"
  },
  "scheduleB": {
    "JobC": "c.js 600"
  },
  "scheduleC": {
    "JobD": "d.js 400"
  },
  "scheduleD": {
    "JobE": "e.bat 200",
    "JobF": "f.js 0"
  }
};

var wait = (job, sleepTime) => {
  return new Promise(function (resolve) {
    setTimeout(() => { resolve(job + ' - Completed'); }, sleepTime);
  });
}

var executeSchedule = (sched, jobs) => {
  console.log('Processing Schedule : ' + sched);
  const stack = Object.values(jobs).map(script => {
    const args = script.split(' ');
    return wait(args[0], args[1])
  })

  return Promise.all(stack)
    .then(resp => {
      // NOTE: this .then is useless
      console.log("After Results are: " + resp);
      return resp
    });
}

const start = async () => {
  const serial = Object.entries(schedule)
  const results = []
  const next = async () => {
    if (serial.length > 0) {
      const [key, value] = serial.shift()
      const out = await executeSchedule(key, value)
      results.push(out)
      return next()
    }
    return results
  }
  return next()
}


start()
  .then(results => {
    console.log('Response : ' + JSON.stringify(results, null, 2));
  })
  .catch(err => {
    console.log('Error : ' + err);
  });