Promises are objects that represent the eventual completion or failure of an asynchronous operation. They provide a way to handle asynchronous
operations in a more organized and manageable manner. To use await, you need to ensure that you are calling a function or an expression
that returns a promise.
The reason await should only be used on a promise is that it expects the operand to be a promise object. When you use
await, it waits for the promise to be resolved or rejected and then returns the resolved value or throws the rejection reason,
respectively. If the operand of await is not a promise, awaiting it is redundant and might not have been the developer’s
intent.
If you try to use await on a non-promise value, such as a regular object or a primitive type, it will not pause the execution of the
function because there is no asynchronous behavior involved. Instead, await will convert the value to a resolved promise, and waits for
it.
const x = 42; await x; // Noncompliant: x is a number, not a promise
You should only use await on promises because it is designed to handle asynchronous operations and works in conjunction with the
Promise API to provide a clean and intuitive way to write asynchronous code in JavaScript.
const x = Promise.resolve(42); await x;
When calling a function that returns a promise as the last expression, you might forget to return it, especially if you refactored your code from a single-expression arrow function.
function foo() {
Promise.resolve(42);
}
async function bar() {
await foo(); // Noncompliant
}
Make sure that you return the promise.
function foo() {
return Promise.resolve(42);
}
async function bar() {
await foo(); // Compliant
}
Another common reason for this issue is a mismatch between JSDoc annotations and async function signatures. When a JSDoc @returns tag
specifies a non-Promise type on an async function, the analyzer trusts the annotation and considers the return type to be non-awaitable,
even though async functions always return a Promise.
/**
* @returns {boolean} True if the lock was set successfully.
*/
async function lock() {
return await someAsyncOperation();
}
async function bar() {
await lock(); // Noncompliant: JSDoc says lock() returns boolean, not a Promise
}
Make sure to wrap the return type in Promise to match the async function signature.
/**
* @returns {Promise<boolean>} True if the lock was set successfully.
*/
async function lock() {
return await someAsyncOperation();
}
async function bar() {
await lock(); // Compliant
}