On Wednesday, May 3, 2017 at 11:55:59 PM UTC+2, Peter B. wrote:
>
>
> I need your help. I'm working on a project and I have a problem with the
> fact that nodejs is asynchronous.
> I want to export my variable called 'macAd'. But even with a global
> variable, I can't do it.
>
If I understood correctly, you want to export macAd? But later you don't
see this variable? Well, it might take a few words to explain, but it's a
simple thing really.
The problem is if you do something like:
let macAd; // *undefined*
module.exports = macAd; // again, *undefined*
macAd = 3; // doesn't matter now, because the exports is bound to
*undefined* already
if you require it later, you'll get *undefined*, not a reference to your
variable. It's passed by value.
But if you export an object instead, you can modify that object later (say,
by setting a *macAd* property), without changing the reference to the
object - which means whoever required the module will get to resolve the
value after you set it.
Have your module set up like this:
const macAd = require('macad')
const obj = {
macAd: undefined,
};
module.exports = obj;
// Now the export has a firm grip on our object. EVen if the value is
undefined itself, the object is there and it'll be
// useful later.
console.log(obj); // -> { macAd: undefined };
macAd.getMac(function (err, mac) {
// obviously handle error first.
obj.macAd = mac;
console.log(obj); // -> { macAd: '::1' };
});
Then, when you require the module later, at first it's going to be
undefined, but later it should resolve to your value. E.g.
const myModule = require('./whatever-you-named-it');
const TIMEOUT = 1000; // or however long the 'macad' module takes.
console.log(myModule.macAd); // -> *undefined*
setTimeout(function () {
console.log(myModule.macAd); // -> *should give you ::1 or something.*
}, TIMEOUT);
Now you have a problem though, your module is async, but you're not sure
when is it complete and when it's safe to use it. That TIMEOUT might be
either too much for you or maybe too short if the computer is busy.
You can get around that by wrapping the *getMac* call in an initializer
function, like this:
const macAd = require('macad')
const obj = {
macAd: undefined,
initialize: function () {
// I use a promise but yuou can go with a callback too
return new Promise(function(resolve, reject) {
macAd.getMac(function (err, mac) {
if (err) {
return reject(err);
obj.macAd = mac;
resolve();
});
});
}
};
module.exports = obj;
console.log(obj); // { macAd: undefined, initialize: [Function] }
Now you can require a module, and call *initialize* on it, and you'll get a
promise resolved (or rejected) when the *macAd* is available, like this:
const myModule = require('myModule');
console.log(myModule.macAd); // most likely *undefined*
myModule.initialize()
.then(function() {
// now myModule.macAd is available.
console.log(myModule.macAd); // ::1
})
.catch(console.error);
But here we have other issues. For one, you might simply call getMac
directly elsewhere like this, there's no direct benefit in wrapping it in
its own module. And another thing - every time you call your module, the
getMac is going to be resolving. In this particular case it might not be a
big issue, but what if it wasn't a *getMac*? What if it was something
calling an expensive 3rd party service? You call it every time you call
this.
That's why you basically store a reference to that promise, and only call
the full init once - every other time you return what you already have.
const macAd = require('macad')
let initPromise; // by keeping it out of *obj*, you're keeping it private
to the module itself.
const obj = {
macAd: undefined,
initialize: function () {
// first check if another module already called init - then just
resolve what we have, they don't have to wait for *getMac*
if (initPromise) {
return initPromise;
}
// if it *wasn't* already called, call macAd now and store the
resulting promise in initPromise.
initPromise = new Promise(function (resolve, reject) {
macAd.getMac(function (err, mac) {
if (err) {
return reject(err);
}
obj.macAd = mac;
});
});
return initPromise;
}
};
module.exports = obj;
Hope this helps you out a bit.
--
Job board: http://jobs.nodejs.org/
New group rules:
https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules:
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/nodejs/0fa8243b-3688-4817-bbbe-cb6c5edc5e41%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.