2

I've defined the following JavaScript function

async isDataValid (externalValidation = true) {
    const isValid = (await this.v$.$validate()) && externalValidation
    // other stuff not relevant to my question happens here
    return isValid
}

AFAIK, I need to define this as an async function in order to await the result of this.v$.$validate().

Because isDataValid is itself async, I thought I need to use await whenever I call it, but when I did the following:

const result = await this.isDataValid()

My IDE marked this with a warning

Redundant 'await' for a non-promise type

So it seems my IDE is saying that await only needs to be used if an async function returns a promise i.e. there is no need to use await with isDataValid because it returns a boolean.

Does await need to be used when calling all async functions, or only those that return a promise?

Update

I am using JavaScript, not TypeScript

Antonio Dragos
  • 1,973
  • 2
  • 29
  • 52
  • 3
    Sure that `(await this.v$.$validate())` isnt't throwing the warning? This `const result = await this.isDataValid()` is totally correct as `async` functions will always return a `Promise`. – Ric Hard Nov 09 '22 at 12:37
  • Are you using typescript? – Nick Parsons Nov 09 '22 at 12:40
  • Perhaps try adding a `;` so that you have `await this.isDataValid();`, the code after that line of code (which isn't shown in your question), might be accidentally chaining what you're awaiting. Otherwise, check that your IDE is up to date – Nick Parsons Nov 09 '22 at 12:57
  • Functions marked with the `async` keyword **ALWAYS** returns a promise. Your IDE is confused – slebetman Nov 10 '22 at 06:51

2 Answers2

1

await is not necessary when using async.

Though if you are using async, it is inferred that your function returns a promise.

The async is a function that is bound with a function that function returns the Promise object. The await operator holds the execution of the Promise function as long as the Promise is completely fulfilled.

As your function- isDataValid is not returning a promise in the first cycle, IDE marks the await as redundant.

The solution here is to return a promise from isDataValid function. Give the return type of isDataValid as Promise<Boolean> and make sure you in-real return a promise.

Ritik Banger
  • 2,107
  • 5
  • 25
  • 1
    _ isDataValid is not returning a promise_ - that is incorrect. The function _is_ returning a promise. Every async function returns a promise, even if it's not explicitly stated in its body: `async function foo() { return 2 + 2; }` will return 4 wrapped in a promise. – mbojko Nov 09 '22 at 12:52
  • @mbojko He mentioned in the first cycle. – Ankit Dhoot Dec 06 '22 at 12:48
1

If you put await in front of a non promise, it will be auto wrapped in a promise and the value will be fulfilled (but in the next cycle). The execution order will definitely change.

Does await need to be used when calling all async functions, or only those that return a promise?

You are going about it the wrong way. Do not think whether await needs to be used when calling all async functions, or only those that return a promise.

async is only used when a function returns a promise. If you are using it for functions that do not return a promise, then you probably do not need it.

The async function returns a Promise. This promise will be resolved with the boolean value. isValid is a promise because even if it looks like a plain Boolean, notice that the value will only be evaluated once the (await this.v$.$validate()) is fulfilled. So if you picture it in .then chaining mechanism, the value will be evaluated inside the then block and then the whole Promise will be resolved.

Something like this:

let isDataValid = () => new Promise((resolve) => {
this.v$.$validate().then((resolvedValidate) => {
  let isValid = resolvedValidate && externalValidation; 
  resolve(isValid);
});
});

In your case, I think the IDE is not able to figure out that isValid is actually going to be a Promise<boolean>. Either explicitly mark the return type like:

async isDataValid (externalValidation = true) : Promise<boolean> {
    const isValid = (await this.v$.$validate()) && externalValidation
    // other stuff not relevant to my question happens here
    return isValid
}

or ignore the warning.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39