Javascript 函数内部未更新全局变量
给定以下代码Javascript 函数内部未更新全局变量,javascript,node.js,Javascript,Node.js,给定以下代码 var base64 = '' const AWS = require('aws-sdk') let awsConfig = { 'region': 'us-west-2', 'endpoint': 'http://dynamodb.us-west-2.amazonaws.com', 'accessKeyId': 'ABCDEFGHIJKLMANOPQRSTUVWXYZ', 'secretAccessKey': 'ABCDABSDJFGJALGJADSLGJALKD
var base64 = ''
const AWS = require('aws-sdk')
let awsConfig = {
'region': 'us-west-2',
'endpoint': 'http://dynamodb.us-west-2.amazonaws.com',
'accessKeyId': 'ABCDEFGHIJKLMANOPQRSTUVWXYZ',
'secretAccessKey': 'ABCDABSDJFGJALGJADSLGJALKDJGALKSDJGLA'
}
AWS.config.update(awsConfig)
let docClient = new AWS.DynamoDB.DocumentClient()
let fetchOneByKey = function () {
var params = {
TableName: 'test',
Key: {
'key1': 'abc'
}
}
docClient.get(params, function (err, data) {
if (err) {
console.log('test::fetchOneByKey::error - ' + err)
} else {
base64 = data.Item.b.toString('base64')
}
})
}
fetchOneByKey()
console.log(base64)
出于某种原因,我的变量base64
不打印任何内容。这很奇怪,因为当我执行console.log(data.Item.b.toString('base64')
时,它会打印base64
字符串,所以我知道数据肯定不是空的
由于某些原因,我的变量没有得到更新,我也不知道为什么。我显然在调用函数fetchOneByKey()
,因此理论上base64
应该得到更新,但它没有得到更新。docClient.get()
是异步的。通过调用console.log()
调用函数后,在从DB读取完成之前立即执行该函数,因此不会更新变量
在此处调用console.log(base64)
else {
base64 = data.Item.b.toString('base64')
console.log(base64)
}
如果您想摆脱回调并使用承诺,那么可以使用。使用它,您可以将其转换为承诺,并与async/await
一起使用,或者与一起使用。then()
或者你也可以手工做出承诺
let fetchOneByKey = function () {
var params = {
TableName: 'test',
Key: {
'key1': 'abc'
}
}
return new Promise((resolve, reject) => {
docClient.get(params, function (err, data) {
if (err) {
console.log('test::fetchOneByKey::error - ' + err)
reject(err)
} else {
base64 = data.Item.b.toString('base64')
resolve(base64)
}
})
}
}
然后您可以说base64=wait fetchOneByKey();
或者,如果您不在async
函数中,则可以执行fetchOneByKey()。然后(base64=>console.log(base64))
编辑:
正如@AZ_u所提到的,aws sdk
支持承诺
let fetchOneByKey = async function () {
var params = {
...
}
const data = await docClient.get(params).promise();
base64 = data.Item.b.toString('base64');
return base64
}
docClient.get()
是异步的。通过在调用函数后立即调用console.log()
,可以在从数据库读取完成之前执行该函数,因此不会更新变量
在此处调用console.log(base64)
else {
base64 = data.Item.b.toString('base64')
console.log(base64)
}
如果您想摆脱回调并使用承诺,那么可以使用。使用它,您可以将其转换为承诺,并与async/await
一起使用,或者与一起使用。then()
或者你也可以手工做出承诺
let fetchOneByKey = function () {
var params = {
TableName: 'test',
Key: {
'key1': 'abc'
}
}
return new Promise((resolve, reject) => {
docClient.get(params, function (err, data) {
if (err) {
console.log('test::fetchOneByKey::error - ' + err)
reject(err)
} else {
base64 = data.Item.b.toString('base64')
resolve(base64)
}
})
}
}
然后您可以说base64=wait fetchOneByKey();
或者,如果您不在async
函数中,则可以执行fetchOneByKey()。然后(base64=>console.log(base64))
编辑:
正如@AZ_u所提到的,aws sdk
支持承诺
let fetchOneByKey = async function () {
var params = {
...
}
const data = await docClient.get(params).promise();
base64 = data.Item.b.toString('base64');
return base64
}
您正试图在调用
docClient.get()之前记录base64
变量
运行。您的控制台.log
不在分配base64
的回调范围内。变量已更新,但您正在更新之前读取值。@Tyleroper如何确保更新发生,以便更新我的var?任何依赖于docClient.get()结果的内容
应在回调内启动,或在等待结果后启动。您正在尝试在docClient.get()的回调之前记录base64
变量
运行。您的控制台.log
不在分配base64
的回调范围内。变量已更新,但您正在更新之前读取值。@Tyleroper如何确保更新发生,以便更新我的var?任何依赖于docClient.get()结果的内容
应该在回调中启动,或者在等待结果之后启动。是的,我知道这是可行的,但我想在函数外部使用该变量。@Dinero使用promisify并将该回调变成承诺。然后可以使用async/await或将其链接到。然后()你能编辑和显示吗?我从来没有使用过我编辑过的。你现在能试试吗?aws sdk
已经提供了承诺包装器。因此不需要单独的新承诺…
。是的,我知道这是可行的,但我想在函数之外使用该变量。@Dinero使用promisify并将该回调变成承诺。然后你可以使用async/wait or您可以将其链接到。然后()您可以编辑和显示吗?我从未使用过我编辑过的。您现在可以尝试吗?aws sdk
已经提供了承诺包装器。因此不需要单独的新承诺…
。