DEV3 Technologies home

DEV3 Developer Forum

Why does my async function return a Promise object instead of the value?

JavaScript helpSolved0 views
dev3 ·
async function getName() { return 'Asha'; }
const name = getName();
console.log(name);  // Promise { 'Asha' }

How do I get the string?

#javascript#async#promises

0

1 reply

dev3 · Accepted answer

Every async function always returns a promise, even if you return a plain value. To get the value you must wait for it.

const name = await getName();            // inside another async function
getName().then((name) => console.log(name));

Top-level await

In ES modules (.mjs, "type": "module", browser module scripts, Next.js server files) you can write await at the top level:

const data = await fetch(url).then((r) => r.json());

In CommonJS you need an async wrapper:

(async () => {
  const name = await getName();
  console.log(name);
})();

Passing the value around

You cannot make asynchronous code synchronous. Either propagate async up the call chain, or store the result in a callback/state:

// React
useEffect(() => {
  getName().then(setName);
}, []);

Do not pass an async function directly as the effect: useEffect(async () => ...) returns a promise instead of a cleanup function.

Error handling

Errors thrown inside become rejections:

try {
  await getName();
} catch (err) {
  // handle
}
// or
getName().catch(handle);

Forgetting to handle them gives "unhandled promise rejection", which crashes Node 15+ processes by default.

Forgotten await

A very common bug:

if (isAllowed(user)) { ... }   // isAllowed is async, so this is always truthy

Linters (@typescript-eslint/no-floating-promises, no-misused-promises) catch these.

Pitfall: return await inside try is needed if you want the catch block to handle the rejection; plain return promise skips it.

0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.