2

On my learning journey, I have started to look at modules for javaScript/Node. What is confusing me is how to return information from a module when the time to complete the functions within a module is unknown.

This returns as expected:

controller.js

const myModule = require('./myModule');
var myWord = myModule.myExp();
console.log(myWord); //returns "Hello World"

myModule.js

module.exports = {
    myExp: function(){
        return mytimeOut();
    }
}

function mytimeOut(){
 var myWord = "Hello World";
 return myWord;
}

What I cannot seem to grasp, is the best way to return myModule when there is an indefinite time to bring back the required result.

How do I get the controller to show "Hello World" and not "Undefined" in the example below. I have read about callbacks, promises, async/await - but without any over-complications, I cannot seem to find a simple solution for this.

controller.js

const myModule = require('./myModule');
var myWord = myModule.myExp();
console.log(myWord); //returns undefined

myModule.js

module.exports = {
    myExp: function(){
        return mytimeOut();
    }
}

function mytimeOut(){
    setTimeout(() => {
        myWord = "Hello World";
        return myWord;

    }, 5000);
}
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – nicholaswmin Jan 07 '19 at 13:06
  • You use it the same way you use any asynchronous function. Simply export the function and call it using any async-programming technique, e.g: error-first callbacks, Promises, `async` functions. – nicholaswmin Jan 07 '19 at 13:07
  • Possible duplicate of [Node.js: unable to return value from other function inside same file](https://stackoverflow.com/questions/50296339/node-js-unable-to-return-value-from-other-function-inside-same-file) – Dan O Jan 07 '19 at 13:12
  • Thank you. This may be a duplicate. I am reading through your suggested duplicates now. – Terence E. Uttley Jan 07 '19 at 13:24

4 Answers4

1

Here's a working copy using async/await

const exports = {
  myExp: function() {
    return mytimeOut();
  }
}

function mytimeOut() {
  return new Promise((resolve) => {
    setTimeout(() => {
      const myWord = "Hello World";
      resolve(myWord);
    }, 5000);
  });
}

(async () => {
  const output = await exports.myExp();
  document.getElementById('output').textContent = output;
})();
<div id="output"></div>
Andy
  • 61,948
  • 13
  • 68
  • 95
1

You can achieve that using async/await.

File: myModule.js

function myTimeout() {
  // Create a promise
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("Hello World"); // resove the promise after those 5 seconds
    }, 5000);
  })
}

module.exports = {
  myExp: function() {
    return myTimeout();
  }
};

File: controller.js

const myModule = require('./myModule');

async function findMyWord() {
  const myWord = await myModule.myExp();
  console.log('My word is:', myWord);
}

findMyWord();

I wrapped everything in an async function because otherwise you will receive the Syntax Error: await is only valid in async error.

Gamote
  • 678
  • 5
  • 17
0

Using async/await:

  // myModule.js

  function mytimeOut() { 
    return new Promise(resolve => 
      setTimeout(() => resolve('Hello World'), 5000)
    )
  }

  // controller.js

  async function init() {
    var myWord = await myModule.myExp()
    console.log(myWord)
  }
  init()
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
0

You need to use Promise, because setTimeout does not return a promise that could be awaited.

File: myModule.js

'use strict';

module.exports = {
  myExp: function() {
    return mytimeout();
  }
};

function mytimeout() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Hello World');
    }, 1000);
  }); 
}

File: controller.js (.then())

'use strict';

const myModule = require('./myModule.js');
myModule.myExp().then(console.log);
Alex M.
  • 129
  • 5