[英]nodejs enable async function return value in global scope
I need to use a value returned by an asynchronous function into a get request.我需要将异步函数返回的值用于 get 请求。 This is my code:
这是我的代码:
let pwd;
async function getSecret() {
const [version] = await smClient.accessSecretVersion({
name: pgpwd
});
const pwd = version.payload.data.toString();
console.log(`in ${pwd}`);
return pwd;
}
promise1 = getSecret().then((pwd) => console.log(`promise then ${pwd}`) );
console.log(promise1.then((pwd) => console.log(`promise1 ${pwd}`)));
console.log(`global scope pwd ${pwd}`);
app.get('/pwd', (req, res) => {
console.log(`get ${pwd}`);
res.send(`pwd = ${pwd}!`);
});
I receive the value in promise.then but it is undefined in the global scope.我收到了 promise.then 中的值,但它在全局范围内未定义。
2020-09-20 11:27:00.909 > node index.js
2020-09-20 11:27:00.909
2020-09-20 11:27:02.152 GET200363 B2 sPostmanRuntime/7.26.5 https://nodejs1-
2020-09-20 11:27:03.379 get undefined
2020-09-20 11:27:03.445 in 123456
2020-09-20 11:27:03.445 promise then 123456
2020-09-20 11:27:03.445 promise1 undefined
2020-09-20 11:27:04.634 get undefined
You don't need a global variable at all.您根本不需要全局变量。 Make your GET request callback
async
as well and await
the result of your getSecret
function in the callback.使您的 GET 请求回调也
async
,并await
回调中await
getSecret
函数的结果。
If getSecret
is an expensive function to execute then you could wrap a function around it with a closure where the pwd
value is stored in. Then when the function is called it checks if getSecret
has been called before and calls it.如果
getSecret
是一个执行getSecret
的函数,那么你可以用一个闭包来包裹它,其中存储pwd
值。然后当函数被调用时,它会检查getSecret
之前是否被调用过并调用它。 Or when it has been called before just return the result instead of calling getSecret
again.或者当它之前被调用时只返回结果而不是再次调用
getSecret
。
async function getSecret() {
const [ version ] = await smClient.accessSecretVersion({
name: pgpwd
});
const pwd = version.payload.data.toString();
return pwd;
}
function storePwd() {
let pwd = null;
return async function() {
if (pwd === null) {
pwd = await getSecret();
}
return pwd;
};
}
const getPwd = storePwd();
app.get('/pwd', async (req, res) => {
const pwd = await getPwd();
res.send(`pwd = ${pwd}!`);
});
There is no magic to this.这没有什么神奇之处。 You just need to assign it:
你只需要分配它:
let pwd; // global
// ...
getSecret().then((localPwd) => { // renamed to something different so that we
// don't shadow (hide) the global pwd
console.log(`promise then ${localPwd}`);
pwd = localPwd; // assign to global variable
})
That's it.就是这样。 It's just a variable assignment.
这只是一个变量赋值。 Nothing more complicated than that.
没有比这更复杂的了。
Of course, doing it this way means that in the first few milliseconds when your app starts up before getSecret()
returns the value of the global pwd
is still undefined.当然,这样做意味着在
getSecret()
返回之前应用程序启动的最初几毫秒内,全局pwd
值仍然是未定义的。 And if you happen to do a get request at this time you will get undefined.如果您此时碰巧执行了 get 请求,您将获得未定义的信息。 But after that it will have the value you expect.
但在那之后,它将具有您期望的价值。 As long as you are OK with this limitation I don't see anything wrong with what you are doing.
只要您接受此限制,我就看不出您在做什么有任何问题。
However, if you don't want your process to answer that get request then you must not define the get request until getSecret()
returns.但是,如果您不希望您的进程响应该获取请求,那么在
getSecret()
返回之前,您不得定义获取请求。 Normally I would personally write code like this:通常我会亲自编写这样的代码:
getSecret().then((pwd) => {
console.log(`promise then ${pwd}`);
// ALL other app logic such as `get` definitions
// are done inside the promise then:
app.get('/pwd', (req, res) => {
console.log(`get ${pwd}`);
res.send(`pwd = ${pwd}!`);
});
});
If you don't want the then
function to be too long you can instead encapsulate your application logic in another function.如果您不希望
then
函数太长,您可以将应用程序逻辑封装在另一个函数中。 This is nothing new, C/C++ has something like this with the main()
function:这不是什么新鲜事,C/C++ 有这样的
main()
函数:
let pwd;
function init () {
app.get('/pwd', (req, res) => {
console.log(`get ${pwd}`);
res.send(`pwd = ${pwd}!`);
});
}
getSecret().then((localPwd) => {
console.log(`promise then ${localPwd}`);
pwd = localPwd;
init(); // start the app
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.