admin管理员组文章数量:1130349
Let's say I want to export in a single JS module some value which is obtained by calling some async function. What is the mechanism to make the export wait for the result/Promise to be resolved?
As an example code snippet I put this here
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 3000);
});
}
let AS;
go().then((x) => {
AS = x;
});
module.exports = AS;
This function could make any API request. I don't want to export the entire function and call it in other module.
Let's say I want to export in a single JS module some value which is obtained by calling some async function. What is the mechanism to make the export wait for the result/Promise to be resolved?
As an example code snippet I put this here
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 3000);
});
}
let AS;
go().then((x) => {
AS = x;
});
module.exports = AS;
This function could make any API request. I don't want to export the entire function and call it in other module.
Share Improve this question edited Jun 27, 2020 at 9:01 Tigran Sahakyan asked Jun 27, 2020 at 8:53 Tigran SahakyanTigran Sahakyan 4251 gold badge6 silver badges10 bronze badges1 Answer
Reset to default 8Two answers for you:
- With standard JavaScript modules (ESM)
- With CommonJS (CJS), the module system you're using in the example in the question
With Standard JavaScript Modules (ESM)
Now that support for ESM has matured, in most Node.js projects you can switch to ESM from CommonJS by putting "type": "module" in your package.json and changing your require() calls to import statements as necessary. If you can do that, you can use top-level await. With top-level await, you can make your module execution wait for a promise to settle (which makes modules that import from your module wait until the promise settles). So you'd do this:
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 500);
});
}
export const AS = await go();
That exports a named export, but you could also replace that last line with this to do a default export (which is more similar to what you have in your CommonJS code; I prefer to avoid default exports):
export default await go();
Modules using your module don't have to be aware of the fact that the value es from an asynchronous source; they aren't evaluated until your module evaluation has finished (after the promise settles). They just import as usual:
import { AS } from "./promise.js"; // If it's a named export
// import AS from "./promise.js"; // If it's the default export
console.log("AS = " + AS);
With CommonJS (CJS)
With CommonJS, your best bet is to export the promise. That way, code using your module has a standard way to handle the fact that the value may not be available yet — Consuming the promise:
require("./your-moudule")
.then(AS => {
// ...use `AS` here...
})
.catch(error => {
// ...handle the fact we didn't get it here...
});
But if you want to export the value instead, you can, it's just usually not your best approach. You'd do that by exporting an object and then updating its AS property:
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 500);
});
}
module.exports = {AS: undefined};
go().then((x) => {
module.exports.AS = x;
});
Modules using your module would have to deal with the fact that briefly (probably) during process startup, they'll be getting undefined. Here's code using the module above:
const mod = require("./promise"); // Note: Not destructuring at this point
const timer = setInterval(() => {
const { AS } = mod;
console.log("AS = " + AS);
if (AS) {
clearInterval(timer);
}
}, 100);
If you run that, you'll see AS = undefined ~5 times and then AS = Success!.
In both cases, it makes the code using your module more plex (they have to await the promise or loop when they see undefined). ESM's approach is simpler from that perspective (those modules just don't run until your module is ready).
Let's say I want to export in a single JS module some value which is obtained by calling some async function. What is the mechanism to make the export wait for the result/Promise to be resolved?
As an example code snippet I put this here
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 3000);
});
}
let AS;
go().then((x) => {
AS = x;
});
module.exports = AS;
This function could make any API request. I don't want to export the entire function and call it in other module.
Let's say I want to export in a single JS module some value which is obtained by calling some async function. What is the mechanism to make the export wait for the result/Promise to be resolved?
As an example code snippet I put this here
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 3000);
});
}
let AS;
go().then((x) => {
AS = x;
});
module.exports = AS;
This function could make any API request. I don't want to export the entire function and call it in other module.
Share Improve this question edited Jun 27, 2020 at 9:01 Tigran Sahakyan asked Jun 27, 2020 at 8:53 Tigran SahakyanTigran Sahakyan 4251 gold badge6 silver badges10 bronze badges1 Answer
Reset to default 8Two answers for you:
- With standard JavaScript modules (ESM)
- With CommonJS (CJS), the module system you're using in the example in the question
With Standard JavaScript Modules (ESM)
Now that support for ESM has matured, in most Node.js projects you can switch to ESM from CommonJS by putting "type": "module" in your package.json and changing your require() calls to import statements as necessary. If you can do that, you can use top-level await. With top-level await, you can make your module execution wait for a promise to settle (which makes modules that import from your module wait until the promise settles). So you'd do this:
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 500);
});
}
export const AS = await go();
That exports a named export, but you could also replace that last line with this to do a default export (which is more similar to what you have in your CommonJS code; I prefer to avoid default exports):
export default await go();
Modules using your module don't have to be aware of the fact that the value es from an asynchronous source; they aren't evaluated until your module evaluation has finished (after the promise settles). They just import as usual:
import { AS } from "./promise.js"; // If it's a named export
// import AS from "./promise.js"; // If it's the default export
console.log("AS = " + AS);
With CommonJS (CJS)
With CommonJS, your best bet is to export the promise. That way, code using your module has a standard way to handle the fact that the value may not be available yet — Consuming the promise:
require("./your-moudule")
.then(AS => {
// ...use `AS` here...
})
.catch(error => {
// ...handle the fact we didn't get it here...
});
But if you want to export the value instead, you can, it's just usually not your best approach. You'd do that by exporting an object and then updating its AS property:
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 500);
});
}
module.exports = {AS: undefined};
go().then((x) => {
module.exports.AS = x;
});
Modules using your module would have to deal with the fact that briefly (probably) during process startup, they'll be getting undefined. Here's code using the module above:
const mod = require("./promise"); // Note: Not destructuring at this point
const timer = setInterval(() => {
const { AS } = mod;
console.log("AS = " + AS);
if (AS) {
clearInterval(timer);
}
}, 100);
If you run that, you'll see AS = undefined ~5 times and then AS = Success!.
In both cases, it makes the code using your module more plex (they have to await the promise or loop when they see undefined). ESM's approach is simpler from that perspective (those modules just don't run until your module is ready).
本文标签:
版权声明:本文标题:javascript - NodeJS, JS how to export Promise value in a module, not the function? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/questions/1744776770a2116077.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论