Disposables: Async Disposables

This functionality requires HHVM 3.24 or later, and is currently experimental.

Async disposables implement IAsyncDisposable instead of IDisposable:

/**
  * Objects that implement IAsyncDisposable may be used in await using statements
  */
interface IAsyncDisposable {
  /**
   * This method is invoked exactly once at the end of the scope of the
   * await using statement, unless the program terminates with a fatal error.
   */
  public function __disposeAsync(): Awaitable<void>;
}

For example:

<?hh

namespace Hack\UserDocumentation\Examples\AsyncDisposables\Simple;

class Handle implements \IAsyncDisposable {
  public async function __disposeAsync(): Awaitable<void> {
    print("Disposing\n");
  }
}

async function main(): Awaitable<void> {
  print("doing stuff\n");
  await using new Handle();
  print("doing more stuff\n");
}

main();
Output
doing stuff
doing more stuff
Disposing

Async disposables can also be combined with async factory functions:

<?hh

namespace Hack\UserDocumentation\Examples\AsyncDisposables\AsyncFactory;

class Handle implements \IAsyncDisposable {
  public async function __disposeAsync(): Awaitable<void> {
    print("Disposing\n");
  }
}

<<__ReturnDisposable>>
async function make_handle_async(): Awaitable<Handle> {
  return new Handle();
}

async function main(): Awaitable<void> {
  print("doing stuff\n");
  await using await make_handle_async();
  print("doing more stuff\n");
}

main();
Output
doing stuff
doing more stuff
Disposing