I have the following code. My intention is to start a task (which involves a few await
calls before it can actually start). When it finishes starting it, I need to update the UI to tell user that the task has started and is waiting for result. Result will come in later so I want to return another Promise
so the app knows when to update the UI with returned result:
async function startSomethingAsync() { await new Promise(r => globalThis.setTimeout(r, 1000)); console.log("Task started"); const finishedPromise = new Promise<number>(r => { globalThis.setTimeout(() => r(100), 3000); }); return finishedPromise; } (async() => { // resultPromise is number instead of Promise<number> const resultPromise = await startSomethingAsync(); // My intention: update UI after starting the task console.log("Task started"); // Then when the result is there, do something else // Currently this is not compiled because resultPromise is not a Promise resultPromise.then(r => console.log("Result arrived: " + r)); })();
However the above code does not work. Somehow resultPromise
is number
(100 after resolved) instead of Promise<number>
. TypeScript also recognize startSomethingAsync
returning Promise<number>
instead of Promise<Promise<number>>
.
Why is this happening? Shouldn’t the async
method wrap another Promise outside of the returned Promise? How do I achieve what I am trying to do and is it a “good” pattern?
I even tried wrapping it by myself:
async function startSomethingAsync() { await new Promise(r => globalThis.setTimeout(r, 1000)); console.log("Task started"); const finishedPromise = new Promise<Promise<number>>(r1 => r1(new Promise<number>(r2 => { globalThis.setTimeout(() => r2(100), 3000); }))); return finishedPromise; }
The function still returns Promise<number>
instead of Promise<Promise<number>>
.
Advertisement
Answer
As we discussed in the comments – you have to wrap the resulting promise in a function or an object.
async function startSomethingAsync() { await new Promise(r => setTimeout(r, 1000)); const finishedPromise = new Promise(r => { setTimeout(() => r(100), 3000); }); return () => finishedPromise; } (async () => { const resultPromise = await startSomethingAsync(); resultPromise().then((r) => console.log("Result arrived: " + r)); })();