Skip to content

proposal: Add then method to better integrate with promises and async await #14

Description

@hrajchert

The idea is to better integrate Task with Promises/Async-Await. If you want to use some code that it's written with Task, and you don't particularly care about the error (for example inside unit tests) you could easily call it between an async function.

(async () => {
    const task = Task.resolve('wii');
    const val = await task;
    console.log(val); // wii!
})();

Notice that we lose the error types

(async () => {
    const task = Task.reject('Oh no'); // Task<never, string>
    try {
        const val = await task;
    } catch (err) {
        err; // any
        console.log(val); //Oh no!
    }
})();

It should be noted (and made super clear in the documentation) that task continues to be Lazy, and by calling then or await we are explicitly forking the task.

The initial POC is implemented in the branch feat-awaitable.


In ts-task/utils we have some proposals for handling the other way. If we have a code that heavily uses async await, not caring about the errors, and we want to control them at some point, we could use chainP and asGuardedError.

async function foo (n: number) {
    if (n === 1) {
        throw 'Buu';
    } 
    return n;
}

Task.resolve(1).pipe(
    chainP(val => foo(val))
); // Task<number, UnknownError>


function isString (val: any): val is string {
    return typeof val === 'string';
}

const asString = asGuardedError(isString);


Task.resolve(1).pipe(
    chainP(foo, asString)
); // Task<number, UnknownError | string>

The chainP function allows us to chain async functions (or functions that returns a promise) inside our Task recipe. If the function throws and we didn't provide the second argument, then the Task will continue on the error side with an UnknownError. But if a guard function is provided, the error of the task will be UnknownError | string.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions