Let's say I have a file containing certain promises, that when executed in order, prepares an input file input.txt
.
// prepareInput.js
var step1 = function() {
var promise = new Promise(function(resolve, reject) {
...
});
return promise;
};
var step2 = function() {
var promise = new Promise(function(resolve, reject) {
...
});
return promise;
};
var step3 = function() {
var promise = new Promise(function(resolve, reject) {
...
});
return promise;
};
step1().then(step2).then(step3);
exports.fileName = "input.txt";
Let's say I have a file containing certain promises, that when executed in order, prepares an input file input.txt
.
// prepareInput.js
var step1 = function() {
var promise = new Promise(function(resolve, reject) {
...
});
return promise;
};
var step2 = function() {
var promise = new Promise(function(resolve, reject) {
...
});
return promise;
};
var step3 = function() {
var promise = new Promise(function(resolve, reject) {
...
});
return promise;
};
step1().then(step2).then(step3);
exports.fileName = "input.txt";
If I run node prepareInput.js
, the line step1().then(step2).then(step3)
gets executed and creates the file.
How can I alter this so that when other files attempt to retrieve fileName
from this module, step1().then(step2).then(step3);
is run and pleted before fileName is exposed? Something along the line of:
// prepareInput.js
...
exports.fileName =
step1().then(step2).then(step3).then(function() {
return "input.txt";
});
// main.js
var prepareInput = require("./prepareInput");
var inputFileName = require(prepareInput.fileName);
Node.js beginner here; apologize beforehand if my approach makes pletely no sense... :)
Share Improve this question edited Jul 11, 2016 at 17:20 Dave Newton 160k27 gold badges260 silver badges307 bronze badges asked Jul 11, 2016 at 15:00 PupperPupper 2,3553 gold badges22 silver badges29 bronze badges 4-
2
Why not
require('./prepareInput').fileName.then(function(inputFileName) {...})
? – Yury Tarabanko Commented Jul 11, 2016 at 15:08 - 1 I mean once your code was "infected" with async effect you can't get rid of it everything that uses the code bees async. – Yury Tarabanko Commented Jul 11, 2016 at 15:10
-
What is
first()
..? – Redu Commented Jul 11, 2016 at 15:14 - @redu: Sorry that meant to say "step1". Yury: trying your suggestion... – Pupper Commented Jul 11, 2016 at 15:17
1 Answer
Reset to default 9You can't directly export the results of something retrieved asynchronously because export is synchronous, so it happens before any async results have been retrieved. The usual solution here is to export a method that returns a promise. The caller can then call that method and use that promise to get the desired async result.
module.exports = function() {
return step1().then(step2).then(step3).then(function() {
// based on results of above three operations,
// return the filename here
return ...;
});
}
The caller then does this:
require('yourmodule')().then(function(filename) {
// use filename here
});
One thing to keep is mind is that if any operation in a sequence of things is asynchronous, then the whole operation bees asynchronous and no caller can then fetch the result synchronously. Some people refer to asynchronous as "contagious" in this way. So, if any part of your operation is asynchronous, then you must create an asynchronous interface for the eventual result.
You can also cache the promise so it is only ever run once per app:
module.exports = step1().then(step2).then(step3).then(function() {
// based on results of above three operations,
// return the filename here
return ...;
});
The caller then does this:
require('yourmodule').then(function(filename) {
// use filename here
});