简体   繁体   中英

What are ways to run a script only after another script has finished?

Lets say this is my code (just a sample I wrote up to show the idea)

var extract = require("./postextract.js");
var rescore = require("./standardaddress.js");

RunFunc();

function RunFunc() {
    extract.Start();
    console.log("Extraction complete");
    rescore.Start();
    console.log("Scoring complete");
}

And I want to not let the rescore.Start() run until the entire extract.Start() has finished. Both scripts contain a spiderweb of functions inside of them, so having a callback put directly into the Start() function is not appearing viable as the final function won't return it, and I am having a lot of trouble understanding how to use Promises. What are ways I can make this work?

These are the scripts that extract.Start() begins and ends with. OpenWriter() is gotten to through multiple other functions and streams, with the actual fileWrite.write() being in another script that's attached to this (although not needed to detect the end of run. Currently, fileWrite.on('finish') is where I want the script to be determined as done

module.exports = {
  Start: function CodeFileRead() {
    //this.country = countryIn;
    //Read stream of thate address components
    fs.createReadStream("Reference\\" + postValid.country + " ADDRESS REF DATA.csv")
      //Change separator based on file
      .pipe(csv({escape: null, headers: false, separator: delim}))
      //Indicate start of reading
      .on('resume', (data) => console.log("Reading complete postal code file..."))
      //Processes lines of data into storage array for comparison
      .on('data', (data) => {
        postValid.addProper[data[1]] = JSON.stringify(Object.values(data)).replace(/"/g, '').split(',').join('*');
        })
      //End of reading file
      .on('end', () => {
        postValid.complete = true;
        console.log("Done reading");
        //Launch main script, delayed to here in order to not read ahead of this stream
        ThisFunc();
      });
  },

  extractDone
}

function OpenWriter() {
    //File stream for writing the processed chunks into a new file
    fileWrite = fs.createWriteStream("Processed\\" + fileName.split('.')[0] + "_processed." + fileName.split('.')[1]);
    fileWrite.on('open', () => console.log("File write is open"));
    fileWrite.on('finish', () => {
      console.log("File write is closed");
    });
}

EDIT: I do not want to simply add the next script onto the end of the previous one and forego the master file, as I don't know how long it will be and its supposed to be designed to be capable of taking additional scripts past our development period. I cannot just use a package as it stands because approval time in the company takes up to two weeks and I need this more immediately

DOUBLE EDIT: This is all my code, every script and function is all written by me, so I can make the scripts being called do what's needed

There's no generic way to determine when everything a function call does has finished.

It might accept a callback. It might return a promise. It might not provide any kind of method to determine when it is done. It might have side effects that you could monitor by polling.

You need to read the documentation and/or source code for that particular function.

Use async/await (promises), example:

 var extract = require("./postextract.js"); var rescore = require("./standardaddress.js"); RunFunc(); async function extract_start() { try { extract.Start() } catch(e){ console.log(e) } } async function rescore_start() { try { rescore.Start() } catch(e){ console.log(e) } } async function RunFunc() { await extract_start(); console.log("Extraction complete"); await rescore_start(); console.log("Scoring complete"); }

You can just wrap your function in Promise and return that.

module.exports = {
  Start: function CodeFileRead() {
    return new Promise((resolve, reject) => {
      fs.createReadStream(
        'Reference\\' + postValid.country + ' ADDRESS REF DATA.csv'
      )
      // .......some code...
      .on('end', () => {
        postValid.complete = true;
        console.log('Done reading');
        resolve('success');
      });
    });
  }
};

And Run the RunFunc like this:

async function RunFunc() {
  await extract.Start();
  console.log("Extraction complete");
  await rescore.Start();
  console.log("Scoring complete");
}

//or IIFE
RunFunc().then(()=>{
  console.log("All Complete");
})

Note: Also you can/should handle error by reject("some error") when some error occurs.

EDIT After knowing about TheFunc():

Making a new Event emitter will probably the easiest solution:
eventEmitter.js

const EventEmitter = require('events').EventEmitter
module.exports = new EventEmitter()
const eventEmitter = require('./eventEmitter');
module.exports = {
  Start: function CodeFileRead() {
    return new Promise((resolve, reject) => {
      //after all of your code
      eventEmitter.once('WORK_DONE', ()=>{
        resolve("Done");
      })
    });
  }
};
function OpenWriter() {
  ...
  fileWrite.on('finish', () => {
    console.log("File write is closed");
    eventEmitter.emit("WORK_DONE");
  });
}

And Run the RunFunc like as before.

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