1

From what I understand after reading this question, require(ModuleName) is a synchronous operation.

In the register-rmq.js I have written the following:

const amqp = require('amqplib/callback_api');

function main(){
    return new Promise(function(resolve,reject){
      amqp.connect('localhost:5672', function(error0, connection) {
        if (error0) {
          throw error0;
        }
        connection.createChannel(function(error1, channel) {
          if (error1) {
            reject(error1);
          }
          channel.assertQueue('', {
            exclusive: true
          }, function(error2, q) {
            if (error2) {
              reject(error2);
            }
          });
          resolve(channel); //
        });
      });
    })
}

main().then(function(result){
    module.exports = {result}
})

In my controller.js I have the following two lines of code:

var channel = require('./register-rmq');
console.log(channel);

What I am expecting from the code is that the line after requiring the module in contoller.js gives me the object that I am expecting from the module which I am requiring, however the console.log that I have in controller.js gets executed before the promise gets return and therefore the channel object is empty in the controller.

Is code I have written is wrong? or Am I confused about how the operation works in this context?

Community
  • 1
  • 1
Benjamin
  • 3,499
  • 8
  • 44
  • 77
  • I've never seen someone define `module.exports` inside a promise callback, I'm not even sure what that would do. It won't work the first time the file is required, but I'm not sure if it's possible for it to be required LATER, by some later file, and have it work... – TKoL Feb 25 '20 at 10:25
  • @TKoL It a node environment, it would always be an empty object. – George Feb 25 '20 at 10:29
  • @TKoL, Thank you, you are right. I did not know the correct way to export it and I thought the right place to do so is inside the callback. – Benjamin Feb 25 '20 at 10:30
  • 1
    @George actually I've just tested it, and that's not true. It is NOT always an empty object. If you define `module.exports` in one file after a 30 second promise callback, and you require that file from a different file after a different 30 second promise callback, it actually works in the second file! – TKoL Feb 25 '20 at 10:32
  • There's obvious reasons why that's not the correct way to do it, but it is possible to require a module export defined asyncronously. – TKoL Feb 25 '20 at 10:33
  • @TKoL Right you are, apologies. Answer updated. – George Feb 25 '20 at 10:36

1 Answers1

2

You've already highlighted that exporting a module is done synchronously; you can't wait until a promise is resolved (or, any asyncronous operation) and expect the correct value to be exported synchronously.

The most appropriate pattern in this scenario would be the following.

register-rmq.js

module.exports = main();

controller.js

var channel = require('./register-rmq');

channel.then(result => console.log(result));
George
  • 36,413
  • 9
  • 66
  • 103