-3

I have seen several linters flag this behaviour but I wonder if this isn't partially why you would use promises:

const promise = myFn()
//do other stuff
const result = myOtherFn(await promise)

Error: promises should be awaited or catch

So is this an incorrect code? If so, why?

Minsky
  • 2,277
  • 10
  • 19
  • 1
    Please update your question with actual linter warnings you see. – STerliakov May 28 '23 at 21:33
  • What is the type of Warning/Error that your linter is complaining about? – underflow May 28 '23 at 21:33
  • The answers to this [other question](https://stackoverflow.com/questions/52654525/using-an-await-in-function-parameter) seem to think what you're doing is fine. – Ouroborus May 28 '23 at 21:43
  • 1
    What linter do you use? Some linters print URLs linking to explanations – jabaa May 28 '23 at 22:21
  • 1
    The issue is that the error handling is missing. There is no `.catch` handler attached immediately (`myFn().catch(......)`) but neither is it instantly `await`ed, so if the promise is rejected before you do the `await`, then you would have an unhandled promise rejection, which you shouldn't have (in node it will crash your process). – CherryDT May 28 '23 at 22:42
  • 1
    @Ouroborus that other question has no `// do other stuff` in between, it has only `const result = myOtherFn(await myFn())` (which would be fine, and the linter wouldn't complain) – Bergi May 28 '23 at 23:55

1 Answers1

3

Yes, this is an unusual usage of await, and a bad practice that might cause your application to crash.

Normally you would immediately await the promise:

const value = await myFn()
// do other stuff
const result = myOtherFn(value);

The problem with not immediately awaiting the promise is that you will miss when it rejects with an error while the // do other stuff is running. If the other stuff is asynchronous, you may await it too late, if the other stuff throws an exception itself, you never await it, and in both cases this causes an unhandled rejection of the promise which will crash your application. See also Waiting for more than one concurrent await operation and Any difference between await Promise.all() and multiple await?.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • What if it is inside a try catch block? Also it seems to completely break the purpose of promises imho – Minsky May 29 '23 at 13:04
  • @Minsky Doesn't matter, the `try` only can catch an exception when once you `await`ed the promise. – Bergi May 29 '23 at 13:29
  • @Minsky Not clear on what you think the purpose of promises is or how it would be broken. – Bergi May 29 '23 at 13:30
  • I think the purpose is to not block the main thread, and you could "start()" a promise so it starts executing the process and only use it when you need by issuing `await` – Minsky May 29 '23 at 15:48
  • Not blocking the main thread is the benefit of asynchronous APIs, but it doesn't require promises. The purpose of promises is to be values representing the eventual result that can be passed around and composed, e.g. using `Promise.all`, but that doesn't mean they should be kept around without immediately handling them. If the "*other stuff*" is asynchronous, you should use `Promise.all` to wait for both results, if it's synchronous, there is no point in calling `myFn()` earlier. – Bergi May 29 '23 at 18:20
  • But if await all promises isn't that exactly than using sync code? – Minsky May 29 '23 at 18:56
  • 1
    No - as I said, you can still do things like `await Promise.all([myFn(), otherStuff()])` if that actually makes sense. Or `Promise.race` etc. And yes, most code is still sequential - the power of asynchronous processing comes from being able to run multiple sequential executions concurrently, e.g. when reacting to events. – Bergi May 29 '23 at 20:49
  • I see, so in some cases when we use a promise but we are actually going to `await` it, and not to do something more event-like for example `myFn().then().catch()` which does not store the value and really uses the power of promises, or use Promise.all and so on; I cases not involving these, we may just use synchronous versions of these functions (i.e were we always await a single operation to store a value), right? – Minsky Jun 18 '23 at 13:56
  • @Minsky No. If you are promises and `await` *inside* your function, it still can be called multiple times and these calls would run concurrently. It's on the caller to exercise this power. If you use synchronous function, you take away that power completely. – Bergi Jun 18 '23 at 16:26