hhvm / hhast

Mutable AST library for Hack with linting and code migrations

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[ DontAwaitInALoop ] allow `return await` in a loop

lexidor opened this issue · comments

We've just converted a function to async that does something database related and is almost always calling in a loop like this.
Is there a reason why return await in a loop is still not a good idea?

We've dumped in a handful of /*HHAST_IGNORE_ERROR*/s.
If there is a reason why this is a bad idea, we'll convert as much as reasonable to the
$bad_example = C\find(...) style and
return await $bad_example->doSomethingDatabaseRelatedAsync().

Code sample like ours

<<__EntryPoint>>
async function main_async(): Awaitable<void> {
    $vec_of_examples = vec[new Example(), new Example(), new Example(), new Example()];
    await business_stuff_async($vec_of_examples);
}

async function business_stuff_async(vec<Example> $vec_of_examples): Awaitable<?TSomethingDatabasy> {
    foreach ($vec_of_examples as $example) {
        if (!$example->isOkay()) {
            /*HHAST_IGNORE_ERROR[DontAwaitInALoop] will never execute more than once, since it returns*/
            return await $example->doSomethingDatabaseRelatedAsync();
        }
    }
    return null;
}

/** All fake ofc */
type TSomethingDatabasy = null;

class Example {
    public function isOkay(): bool {
        return \random_int(0, 5) !== 2;
    }
    public async function doSomethingDatabaseRelatedAsync(): Awaitable<TSomethingDatabasy> {
        await HH\Asio\later(); // Fake database call
        return null as TSomethingDatabasy;
    }
}

Is there a reason why return await in a loop is still not a good idea?

Nope, this makes sense; linter should ignore this.