-3

What is the best way for synchronous execution when working with external modules? I would like the output to result in:

Setp 1: Hello
Setp 2: Hej 
Step 3: Hola  
Step 4: Bonjour

Example:

//File: main.js
var greetings = require("./greetings.js");

console.log(greetings.sayHelloInEnglish());
console.log(greetings.sayHelloInSwedish());
console.log(greetings.sayHelloInSpanish());
console.log(greetings.sayHelloInFrench());

.

//File: greetings.js
module.exports = {
    sayHelloInEnglish: function() {
        return "Step 1: Hello"
    },
    sayHelloInSpanish: function() {

        setTimeout(function (){return "Step 3: Hola"},4000);
    },
    sayHelloInFrench: function() {
        return "Step 4: Bonjour";
    },
    sayHelloInSwedish: function() {
        setTimeout(function (){return "Step 2: Hej"},8000);
    }
};
  • What are you trying to achieve? Why the timeouts? – mbrandau Feb 13 '18 at 15:40
  • As you have tagged the question with "bluebird", "q", and "async.js" you seem to know that you could use promises. But you should be more specific with your question. – str Feb 13 '18 at 15:40
  • 3
    _"What is the best way for synchronous execution when working with external modules?"_ To not do it. Embrace asynchronicity, don't fight it. – James Thorpe Feb 13 '18 at 15:41
  • You are using a timeout, its not really serilizable. If you meant just asynchronous function calls with callbacks, try async. library – Malice Feb 13 '18 at 15:41

2 Answers2

0

Thanks Malice for your suggestion to use async. But it still would be interesting to know if there is a implementation?

The "setTimeout" is to symbolize database request or some other delayed operation.

//File: main.js

var greetings = require("./greetings.js");
var async =  require('async');
async.waterfall([
        function firstStep(done) {
            greetings.sayHelloInEnglish(done);


        },
        function secondStep(step1Result, done) {
            console.log(step1Result);

            greetings.sayHelloInSwedish(done);


            //done(null, 'Value from step 2'); // <- set value to passed to step 3
        },
        function thirdStep (step2Result, done) {
            console.log(step2Result);

            greetings.sayHelloInSpanish(done);

            //done(null, 'Value from step 3'); // <- no value set for the next step.
        },
        function fourthStep (step3Result, done) {
            console.log(step3Result);

            greetings.sayHelloInFrench(done);
            //done(null, 'Value from step 4');
        },
        function fifthStep (step4Result, done) {
            console.log(step4Result);

            greetings.sayHelloInFrench(done);

        }


    ],
    function (err) {
        if (err) {
            throw new Error(err);
        } else {
            console.log('No error happened in any steps, operation done!');
        }
    });

.

//File: greetings.js

module.exports = {

    sayHelloInEnglish: function(callback) {
        callback(null,"Setp 1: HELLO");

    },

    sayHelloInSpanish: function(callback) {

        setTimeout(function (){callback(null,"Step 3: Hola")},8000);

    },

    sayHelloInFrench: function(callback) {
        callback(null, "Step 4: Bonjour");
    },

    sayHelloInSwedish: function(callback) {

        setTimeout(function (){callback(null,"Setp 2: hej!!")},8000);
    }

};
  • What you mean by "_But it still would be interesting to know if there is an implementation?_" – Jaime Mar 09 '18 at 21:52
0

If you have a number of promise-producing functions that need to be run sequentially, you can do it manually:

var greetings = require("./greetings.js");

// File: greetings.js
module.exports = {
    sayHelloInEnglish: function() {
        return Promise.resolve("Step 1: Hello");
    },

    sayHelloInSpanish: function() {
        return Promise.resolve("Step 3: Hola");
    },

    sayHelloInFrench: function() {
        return Promise.resolve("Step 4: Bonjour");
    },

    sayHelloInSwedish: function() {
        return Promise.resolve("Step 2: Hej");
    }
};

// File: main.js
greetings.sayHelloInEnglish()
   .then(() => greetings.sayHelloInSwedish())
   .then(() => greetings.sayHelloInSpanish())
   .then(() => greetings.sayHelloInFrench());

Or

// File: main.js
greetings.sayHelloInEnglish()
   .then(greetings.sayHelloInSwedish)
   .then(greetings.sayHelloInSpanish)
   .then(greetings.sayHelloInFrench);

If you want to run a dynamically constructed sequence of functions, you want something like this:

// File: greetings.js
const functions = [greetings.sayHelloInEnglish, greetings.sayHelloInSwedish, greetings.sayHelloInSpanish, greetings.sayHelloInFrench];

const firstFunction = functions.splice(0, 1)[0];
const result = Promise.resolve(firstFunction());

functions .forEach((current) => {
    result = result.then(current);
});

return result;

There are more compact ways to achieve this. Once you know how it works you can improve it.

Jaime
  • 488
  • 3
  • 8