Disons que c'est mon code (juste un échantillon que j'ai écrit pour montrer l'idée)

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

Et je ne veux pas laisser le rescore.Start () s'exécuter tant que l'extrait.Start () n'est pas terminé. Les deux scripts contiennent une toile d'araignée de fonctions à l'intérieur d'eux, donc avoir un rappel placé directement dans la fonction Start () ne semble pas viable car la fonction finale ne le retournera pas, et j'ai beaucoup de mal à comprendre comment utiliser Promises . Comment puis-je faire en sorte que cela fonctionne?

Ce sont les scripts qui extraient.Start () commence et se termine par. OpenWriter () est accessible via plusieurs autres fonctions et flux, le fichier fileWrite.write () réel étant dans un autre script qui lui est associé (bien qu'il ne soit pas nécessaire pour détecter la fin de l'exécution. Actuellement, fileWrite.on ('finish') est l'endroit où je veux que le script soit déterminé comme terminé

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: Je ne veux pas simplement ajouter le script suivant à la fin du précédent et renoncer au fichier maître, car je ne sais pas combien de temps il sera et il est censé être conçu pour être capable de passer des scripts supplémentaires notre période de développement. Je ne peux pas simplement utiliser un package tel quel, car le temps d'approbation dans l'entreprise prend jusqu'à deux semaines et j'en ai besoin plus immédiatement

DOUBLE EDIT: C'est tout mon code, chaque script et chaque fonction sont tous écrits par moi, donc je peux faire en sorte que les scripts appelés fassent ce qui est nécessaire

1
TheBasementNerd 2 mai 2020 à 00:00

3 réponses

Meilleure réponse

Vous pouvez simplement envelopper votre fonction dans Promise et le renvoyer.

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

Et exécutez le RunFunc comme ceci:

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

Remarque: vous pouvez / devez également gérer l'erreur par reject("some error") lorsqu'une erreur se produit.

MODIFIER Après avoir pris connaissance de TheFunc ():

Créer un nouvel émetteur d'événements sera probablement la solution la plus simple:
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");
  });
}

Et exécutez le RunFunc comme avant.

0
Aritra Chakraborty 1 mai 2020 à 21:36

Il n'y a pas de moyen générique de déterminer quand tout ce qu'un appel de fonction fait est terminé.

Il peut accepter un rappel. Cela pourrait retourner une promesse. Il peut ne fournir aucun type de méthode pour déterminer quand cela est fait. Cela peut avoir des effets secondaires que vous pouvez surveiller en interrogeant.

Vous devez lire la documentation et / ou le code source de cette fonction particulière.

0
Quentin 1 mai 2020 à 21:04

Utilisez async / await (promesses), exemple:

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");
}
0
Aks Jacoves 1 mai 2020 à 21:09