Узлы, использующие async.parallel & async / wait.Есть ли лучший способ сделать это - PullRequest
0 голосов
/ 25 января 2019

Это лучший способ сделать это, ниже работает код, то, что я пытаюсь сделать, это

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

В конечном итоге будет заменена функция wait () на функцию child_process / spawn / exec, которая будет запускать программы .bat & .js в Windows.

Я бы хотел знать,

  1. Есть ли лучший способ написать программу, изначально задумывавшуюся как async.series для обработки основного расписания (в настоящее время async / await используется в start ()).
  2. В executeSchedule в настоящее время я использую async.parallel, также можно использовать async.map. Но то, что я хотел бы знать, есть ли какой-нибудь более простой нативный способ nodejs без использования асинхронной библиотеки (или). Асинхронность здесь лучше подходит.

1 Ответ

0 голосов
/ 25 января 2019

Вы можете сделать это, играя с цепочкой обещаний.

Для сериализации необходимо только реализовать функцию "next" или использовать итерацию, для параллели вы можете просто использовать 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);
  });
...