ken
ken

Reputation: 9013

Why there's no "then" in async functions

I have two identical functions in terms of outcome:

const p1 = async () => {
  return 1;
};

const p3 = new Promise((resolve, reject) => {
  resolve(1);
});

console.log(typeof p1.then);
console.log(typeof p3.then);

I would have expected that both would transpile to have a "then" property but it appears they do not:

enter image description here

But yet vs-code's intellisense notes them as both being promises:

enter image description here

enter image description here

and we can even ensure the return type is the same if we're explicit about p3:

enter image description here

Now I think by definition a Promise is "thenable" right? The reason I find myself caring is that I have an inferred interface in Typescript from the following function:

export const DELAYED = "WAIT_IN_PARALLEL_DELAYED";
export function delayed<T = any>(delayedPromise: () => Promise<T>) {
  return {
    delayed: DELAYED,
    start(resolve, reject) {
      delayedPromise()
        .then(resolve)
        .catch(reject);
    }
  };
}

I'd have thought passing in:

 const test = () => async() => 1;

to the function delayed(test) would be fine but instead it is complaining that test does NOT have ".then". Can someone help me understand the flaw in my thinking?

Upvotes: 0

Views: 115

Answers (2)

Oscar Paz
Oscar Paz

Reputation: 18322

Well, for starters, no, p1 and p3 are not the same. p3 is a Promise, so it does have a then method. But p1 is a function that returns a promise, so it is not a promise, but a function, and as such does not have a then property, just like in const p4 = () => 5 p4 is a function, not a number.

Effectively, your delayed function requires you to pass a function that returns a Promise, though I am not sure why. Shouldn't be easier to just pass the Promise itself? But, anyway, your test function does not match the type of delayedPromise. Why?

Because, in your definition:

delayedPromise: () => Promise<T> // a function that returns Promise<T>
const test = () => async() => 1; // a function that returns a function that returns a Promise

You should define test as

const test = async() => 1;

Hope this helps you.

Upvotes: 4

Felix Kling
Felix Kling

Reputation: 816970

Why there's no “then” in async functions

Async functions return a promise when called (they are not promises themselves). That promise has a then property.

Upvotes: 1

Related Questions