Если бы мне пришлось угадать, это потому, что jwtClient.authorize
принимает обратный вызов вместо возврата обещания -
async function getGoogleApiToken() {
let jwtClient = new google.auth.JWT(...);
await jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
} else {
console.log("Successfully connected!"+ tokens.access_token); //displaying the token correctly
return tokens.access_token; //returns the token // <- NO IT DOESN'T
}
});
}
Обратные вызовы не могут return
значение. Это один из самых популярных вопросов в StackOverflow. Обратные вызовы, подобные тем, которые используются в jwtClient.authorize
, являются просто распространенным шаблоном использования и не взаимодействуют напрямую с async
и await
. Вы должны вернуть Promise
из вашего getGoogleApiToken
. Один из таких способов - обернуть Обещание вокруг вызова jwtClient.authorize
-
async function getGoogleApiToken() {
const jwtClient = new google.auth.JWT(...); // <-- btw use const
return new Promise((resolve, reject) => // <-- wrap in promise
jwtClient.authorize((err, tokens) => {
if (err)
reject(err) // <-- reject the error
else
resolve(tokens) // <-- resolve the result
})
)
}
. Мы не хотим добавлять эту обёртку Обещания каждый раз, когда мы sh используем функцию приема обратного вызова с другими Код на основе обещаний, включая любые функции async
. Превращение любой асин c, принимающей функцию обратного вызова, в асин c, возвращающую обещание, может быть механическим процессом. Фактически это то, что NodeJS s util.promisify делает. Это работает примерно так -
// approximation of util.promisify
const promisify = f => (...args) =>
new Promise ((pass, fail) =>
f (...args, (err, result) => err ? fail(err) : pass(result))
)
// example callback-accepting function
const demoCallbackFunc = (a, b, callback) =>
setTimeout(callback, 1000, null, a + b)
// ordinary call
demoCallbackFunc(3, 5, (err, res) => {
if (err)
console.error(err)
else
console.log(res)
})
// promisified
promisify(demoCallbackFunc)(3, 5)
.then(console.log, console.error)
console.log("please wait 1 second...")
Использование promisify
в вашей программе значительно очистит его -
async function getGoogleApiToken() {
const jwtClient = new google.auth.JWT(...);
const auth = promisify(jwtClient.authorize.bind(jwtClient))
return auth() // <-- no need for await, auth already returns a promise
}
Или без промежуточного назначения auth
-
async function getGoogleApiToken() {
const jwtClient = new google.auth.JWT(...);
return promisify(jwtClient.authorize.bind(jwtClient))()
}
или без bind
с использованием функции стрелки -
async function getGoogleApiToken() {
const jwtClient = new google.auth.JWT(...);
return promisify(callback => jwtClient.authorize(callback))()
}