Search code examples
javascriptnode.jsasynchronoussynchronous

nodejs asynchronous to synchronous


I'm new to nodejs and javascript and I'm currently working on an open source project, since last night I was trying to convert this function from asynchronous to synchronous, but I couldn't, I used async / await but I think that I didn't understand this concept very well, this function encrypts and compresses files using the aes256 algorithm, I works well asynchronously but I want to add this new feature that allows you to encrypt a directory's content recursively.

function encrypt({ file, password }, error_callback, succ_callback) {
    const initVect = crypto.randomBytes(16);

    // Generate a cipher key from the password.
    const CIPHER_KEY = crypto.createHash('sha256').update(password).digest();;
    const readStream = fs.createReadStream(file);
    const gzip = zlib.createGzip();
    const cipher = crypto.createCipheriv('aes-256-cbc', CIPHER_KEY, initVect);
    const appendInitVect = new AppendInitVect(initVect);
    // Create a write stream with a different file extension.
    const writeStream = fs.createWriteStream(path.join(file + ".dnc"));

    readStream
      .pipe(gzip)
      .pipe(cipher)
      .pipe(appendInitVect)
      .pipe(writeStream);

    readStream.on('error', error_callback);
    readStream.on('end', succ_callback);
}

Solution

  • Try using promises. By changing the code slightly you can promisify the function and then wait for all promises to resolve or reject before taking action.

    function encrypt({ file, password }) {
      const initVect = crypto.randomBytes(16);
    
    // Generate a cipher key from the password.
      const CIPHER_KEY = crypto.createHash('sha256').update(password).digest();;
      const readStream = fs.createReadStream(file);
      const gzip = zlib.createGzip();
      const cipher = crypto.createCipheriv('aes-256-cbc', CIPHER_KEY, initVect);
      const appendInitVect = new AppendInitVect(initVect);
    // Create a write stream with a different file extension.
      const writeStream = fs.createWriteStream(path.join(file + ".dnc"));
    
      readStream
        .pipe(gzip)
        .pipe(cipher)
        .pipe(appendInitVect)
        .pipe(writeStream);
    
    
      const promise = new Promise();
      writeStream.on('error', err => promise.reject(err));
      writeStream.on('end', data => promise.resolve(data));
      return promise;
    }
    
    const promise1 = encrypt({file1, password1});
    const promise2 = encrypt({file2, password2});
    
    Promise.all([promise1, promise2])
      .then(succ_callback)
      .catch(error_callback);
    

    I have not run this code so it might need some tweaking to make it work, but this is the general gist.