Home > front end >  How to run a function after map in Electron
How to run a function after map in Electron

Time:11-03

I am encrypting an array of files and using node streams to encrypt a file in chunk. I want to run a function after the encryption is done of all the files in the array but my function runs before the encryption has completed. I am using preload.js to expose the encryption function.

//encrypt.js
const path = require("path");
const fs = require("fs");
const { pipeline } = require("stream/promises");
const { app } = require("./app.js");

async function encrypt(file) {
  const fileReadStream = fs.createReadStream(file);

  const filePath = path.parse(file).dir;
  const fileName = path.parse(file).name;
  const fileExt = path.parse(file).ext;
  const EncFile = filePath   "/"   fileName   "_enc"   fileExt;
  const fileWriteStream = fs.createWriteStream(EncFile);

  await pipeline(
    fileReadStream,
    new Transform({
      transform(chunk, encoding, callback) {
        const encryptedData = app.encrypt(chunk, password);
        callback(null, encryptedData);
        console.log("File encrypted");
      },
    }),
    fileWriteStream
  );
}
module.exports.encrypt = encrypt;
//preload.js
const { encrypt } = require('./encrypt.js');
contextBridge.exposeInMainWorld('encrypt', encrypt);
const para = document.querySelector('#para-info');
const btn = document.querySelector('#btn');
btn.addEventListener("click", () => {
  filesList.map(file => {
    window.encrypt(file, password);
  });
  done();
}

// function i want to run after encryption is done
function done(){
  para.innerText = 'Encryption Done';
}

CodePudding user response:

The function is async:

async function encrypt(file) {

But it's not being awaited:

filesList.map(file => {
  window.encrypt(file, password);
});
done();

One approach is to do all this in an async function to make use of await:

let myFunc = async () => {
  for (let file of filesList) {
    await window.encrypt(file, password);
  }
  done();
};
myFunc();

Or capture the resulting Promise objects and wait for all of them:

let promises = filesList.map(file => {
  return window.encrypt(file, password);
});
Promise.all(promises).then(() => done());

CodePudding user response:

You can make you click handler as async function

const para = document.querySelector('#para-info');
const btn = document.querySelector('#btn');
btn.addEventListener("click", async () => {
   const promises = filesList.map(file => window.encrypt(file, password);
   // Waits for every promise in list
   await Promise.all(promises);

   done();
}

// function i want to run after encryption is done
function done(){
   para.innerText = 'Encryption Done';
}
  • Related