问题
I'm wrapping my dynamoDB function into another function and I'm having issues with returning it to the "item" const. What I'm missing here?
Works:
const params = {
TableName: table,
Key: {
id: id
},
};
dynamoDb.get(params, (error, result) => {
if (error) {
console.error(error);
callback(null, {
statusCode: error.statusCode || 501,
body: 'Couldn\'t fetch the item.',
});
return;
}
const item = result.Item
})
Doesn't work (returns undefinied):
const getFromDb = () => {
const params = {
TableName: table,
Key: {
id: id
},
};
dynamoDb.get(params, (error, result) => {
if (error) {
console.error(error);
callback(null, {
statusCode: error.statusCode || 501,
body: 'Couldn\'t fetch the item.',
});
return;
}
return result.Item
})
}
// Get from db
const item = getFromDb()
// do stuff with result item...
回答1:
What currently happens in your code is getFromDb
function will run dynamoDb.get(...)
and immediately return (undefined in your case, because there is no return statement inside getFromDb
). By the time getFromDb
returns, your dynamoDb request hasn't even resolved yet, it will resolve at some point in the future and call the callback you provided (error, result) => { ... }
To achieve what you described, you need to:
- make
getFromDb
return Promise which will only resolve after your request resolves await
for that function when calling it, getting result into which your Promise resolves (or and error if it rejects)
.
// marking this function async is not required but good to have
// to not forget that this function returns a promise, not immediate result
const getFromDb = async () => {
// wrapped body in a promise
return new Promise((resolve, reject) => {
const params = {
TableName: table,
Key: {
id: id
},
}
dynamoDb.get(params, (error, result) => {
if (error) {
// in case of error, we reject promise with that error
reject(error)
return
}
// otherwise, we resolve with result
resolve(result.Item)
})
})
}
// usage with async/await
// I wrapped significant code in asynchronous function f and then called it
// just to emphasize that you can only use async/await inside async function
// if you are already in async function, you don't need to do this
const f = async () => {
try {
const item = await getFromDb();
console.log(item)
} catch(error) {
// the error we rejected with
console.error(error)
}
}
f()
// alternative way without async/await, using Promise chaining
getFromDb()
.then(item => console.log(item))
.catch(error => console.error(error))
来源:https://stackoverflow.com/questions/58569495/how-to-return-from-nested-function-in-node-js