Rarely do you utilize the then
keyword within an async
function.¹ The primary benefit of utilizing async
functions is the ability to employ await
instead. In this particular scenario, you should assign the outcome of await getActualId()
to the variable id
:
async function fetchId(){
let id:number = await getActualId();
return id;
}
(Although it's not entirely clear why such a function would be necessary, as it appears to only serve as a wrapper for getActualId
.)
An issue exists with the getActualId
function, however, which can be resolved by defining the return type: getActualId
is currently lacking a return type annotation, hence it implicitly returns Promise<any>
. If it should be returning Promise<number>
, then that specification needs to be indicated:
function getActualId(): Promise<number> {
return new Promise(function (resolve) {
chrome.storage.sync.get({
userId: true
}, function (userId) {
resolve(userId.userId);
});
});
}
View example in the online playground here:
function getActualId(): Promise<number> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(Math.floor(Math.random() * 100));
}, 100);
});
}
async function fetchId() {
let id = await getActualId();
return id;
}
If you hover over the variable id
inside the fetchId
function, TypeScript will recognize it as a number
based on the signature of getActualId
, eliminating the need for a redundant type annotation.
¹ When I say "rarely," I truly mean exceedingly rarely. One possible scenario where you might use it is if you have multiple operations to execute concurrently (and are employing Promise.all
) and you need to manipulate the result of one operation. In that case, you could potentially do something like this:
const [first, second, third] = await Promise.all([
firstOp(),
secondOp().then(value => value.toUpperCase()),
thirdOp()
]);
This approach allows the execution of thirdOp
to proceed immediately without being delayed by the completion of secondOp
, as would occur if await
was used on secondOp
.