method TaskClass.prototype.finally
Private
TaskClass.prototype.finally(onFinally?: (() => void) | null): TaskClass<T, E>

Promise.prototype.finally, returning a Task so cleanup does not drop the chain into plain-Promise land. Every spec behaviour is kept: onFinally takes no arguments, its return value is discarded, a thenable it returns is awaited, and anything it throws replaces the outcome.

Prefer try/finally to this. It exists so that calling it on a Task — which is a real Promise, so anyone may — behaves sensibly, not because it is the better spelling. A plain try/finally inside the recipe is better on every axis:

const acquire = async () => ({ read: async () => 'body', release: () => {} });

// preferred: lazy, retryable, and the cleanup runs once per attempt
Task(async () => {
  const handle = await acquire();
  try {
    return await handle.read();
  } finally {
    handle.release();
  }
});

The reason is that this method must be EAGER — finally is overwhelmingly written fire-and-forget (closeWithGrace(...).finally(() => process.exit(143))), and a lazy one nobody awaited would never release. Being eager, it hands back a running Task, so task.finally(cleanup).retry(3) leaves the first attempt's rejection unowned and reports an unhandled rejection. retry first, finally last — or try/finally, which cannot be held wrong this way.

let released = false;
const value = await Task(() => 'body').finally(() => {
  released = true; // runs whichever way the Task settles
});

value; // 'body' — the outcome passes through untouched
released; // true

Parameters

optional
onFinally: (() => void) | null

Return Type

Usage

import { TaskClass } from "lib/task/task.ts";