How to get 3 functions to run synchronously in NodeJS

First question ever. Learned from StackOverflow for years. Just cant figure this out.

I've tried to wrap my head around callbacks, promises and async/await - I'm just not seeing it. Can someone please help?

I just cant get it to do: 1, then 2, then 3.

  1. Download a PDF
  2. Convert PDF to JPGs
  3. Delete PDF
const http = require('http');
const fs = require('fs');
const { exec } = require("child_process");
const targetUrl = 'http://domain/fileProxy.ashx?token=';
const previewpath = 'previews/';

var token = '66a7e572-e2fb-4fb4-87a9-6e19d675357f';
var orderNo = '121212';

function getPdf() {
    var file = fs.createWriteStream(orderNo+ ".pdf");
    http.get(targetUrl+token, function(response) {
        response.pipe(file);
        console.log('downloaded');
    });
}
    
function makeJpgs() {
    exec("magick -density 150 -quality 100% " + orderNo + ".pdf " + previewpath + orderNo + ".jpg");
    console.log('converted');
}

function deletePdf() {
    fs.unlink(orderNo+ ".pdf", (err) => {
        if (err) {
            throw err;
        }
    });
    console.log('deleted');
}

getPdf();
makeJpgs();
deletePdf();

1 answer

  • answered 2020-08-11 00:08 slebetman

    The traditional way of doing it is to continue execution in the callback. The minimal modification needed to get your code working:

    function getPdf() {
        var file = fs.createWriteStream(orderNo+ ".pdf");
        http.get(targetUrl+token, function(response) {
            response.pipe(file);
            console.log('downloaded');
            makeJpgs(); // CONTINUED HERE!
        });
    }
        
    function makeJpgs() {
        // 
        exec("magick -density 150 -quality 100% " + orderNo + ".pdf " + previewpath + orderNo + ".jpg", function (err) {
            if (err) {
                console.error(err);
            }
            else {
                deletePdf(); // CONTINUED HERE!
            }
        });
        console.log('converted');
    }
    
    function deletePdf() {
        fs.unlink(orderNo+ ".pdf", (err) => {
            if (err) {
                console.error(err); // You can't really throw asynchronously
            }
            else {
                // Deletion process completes here.
                console.log('deleted');
            }
        });
        // console.log('deleted'); // Note: The file haven't even started being deleted here
    }
    
    getPdf();
    

    With Promises you can make your code a bit more readable:

    const util = require('util');
    const http = require('http');
    const fs = require('fs');
    const child_process = require("child_process");
    const targetUrl = 'http://domain/fileProxy.ashx?token=';
    const previewpath = 'previews/';
    
    var token = '66a7e572-e2fb-4fb4-87a9-6e19d675357f';
    var orderNo = '121212';
    
    const exec = util.promisify(child_process.exec);
    const unlink = util.promisify(fs.unlink);
    const get = function (url) {
        return new Promise(function(ok,fail){
            http.get(targetUrl+token, function(response) {
                response.pipe(file);
                ok();
            })
            .on('error',fail);
        });
    }
    
    function getPdf() {
        var file = fs.createWriteStream(orderNo+ ".pdf");
        return get(targetUrl+token);
    }
        
    function makeJpgs() {
        return exec("magick -density 150 -quality 100% " + orderNo + ".pdf " + previewpath + orderNo + ".jpg");
    }
    
    function deletePdf() {
        return unlink(orderNo+ ".pdf", (err) => {
            if (err) {
                throw err;
            }
        });
    }
    
    getPdf().then(function(){
        console.log('downloaded');
        return makeJpgs();
    }).then(function(){
        console.log('converted');
        deletePdf();
    }).then(fuction(){
        console.log('deleted');
    });
    

    Now that your functions return promises you can use async/await:

    async function main () {
        await getPdf();
        console.log('downloaded');
        await makeJpgs();
        console.log('converted');
        await deletePdf();
        console.log('deleted');
    }
    
    main().then('done');