npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

thenfail

v0.4.13

Published

Promises/A+ implementation with the ability to break or cancel the chain. Written in TypeScript.

Downloads

149

Readme

NPM Package Build Status

ThenFail v0.4

Just another Promises/A+ implementation written in TypeScript that provides control flow tools like Promise.break, Promise.goto and disposable context.

Documentation

https://vilic.github.io/thenfail/doc

Install

npm install thenfail --save

Usage

import Promise from 'thenfail';

First call

ThenFail added a static then method for the first call, which is equivalent to Promise.resolve().then. While method Promise.resolve can also handle both normal value and promise-like value, using the static then method can make sure errors thrown are caught.

Promise
    .then(() => {
        if (foo) {
            return Promise.resolve('foo');
        } else if (bar) {
            return 'bar';
        } else {
            throw new Error();
        }
    })
    .then(value => {
        console.log(value);
    });

Create promise for event emitters

It is common to pipe a stream to another, taking piping a read stream to a write stream for example:

import * as FS from 'fs';

function copy(src: string, dest: string): Promise<void> {
    let readStream = FS.createReadStream(src);
    let writeStream = FS.createWriteStream(dest);

    readStream.pipe(writeStream);

    // Listen to `close` event of `writeStream` for fulfillment,
    // And listen to `error` event of `writeStream` as well as `readStream` for rejection.
    return Promise.for(writeStream, 'close', [readStream]);
}

Control flow features

Promise.break

Sometimes chaining promises could be annoying. For example:

Promise
    .then(() => {
        // step 1
    })
    .then(() => {
        // step 2
        if (noNeedToContinue) {
            // How to break here?
        }
    })
    .then(() => {
        // step 3.1
    }, reason => {
        // step 3.2
    })
    .then(() => {
        // step 4
    });

Now it's easy with ThenFail:

Promise
    .then(() => {
        // step 1
    })
    .then(() => {
        // step 2
        if (noNeedToContinue) {
            Promise.break;
        }
    })
    .then(() => {
        // step 3.1
    }, reason => {
        // step 3.2
    })
    .then(() => {
        // step 4
    })
    // enclose current context so it won't break too many.
    // it should be required if this could be directly chained somewhere else.
    // e.g. Returned as your method result.
    .enclose();

Promise.goto

Promise
    .then(() => {
        if (someCondition) {
            Promise.goto('label-a');
        } else {
            Promise.goto('label-b');
        }
    })
    .then(() => {
        // will not be called.
    })
    .label('label-a', () => {
        // step 3.1
    }, reason => {
        // step 3.2
    })
    .label('label-b', () => {
        // step 4
        // be aware that `goto` `"label-a"` won't prevent the execution of `"label-b"`.
    });

Promise context

There's situations we may want to cancel a promise chain, not only from inside (like using Promise.break), but also from outside:

page.on('load', () => {
    Promise
        .then(() => {
            // do some works...
        })
        .then(() => {
            // more works...
        })
        .then(() => {
            // ...
        });
});

page.on('unload', () => {
    // how can we cancel the promise chain?
});

With ThenFail, every promise has something called context. And if the context is disposed, the chain gets cancelled.

import { Context } from 'thenfail';

let context: Context;

page.on('load', () => {
    let promise = Promise
        .then(() => {
            // do some works...
        })
        .then(() => {
            // more works...
        })
        .then(() => {
            // ...
        });

    context = promise.context;
});

page.on('unload', () => {
    // dispose the context.
    if (context) {
        context.dispose();
        context = undefined;
    }
});

As what you might guess, The enclose method we mentioned before can mark current context as enclosed, and no longer accept new promises being under the same context. Which means a new context will be created when the then method is called.

Notable basics

States

Promises/A+ defines 3 states of a promise: pending, fulfilled and rejected. And only the pending state may transform to other states.

In the implementation of ThenFail, one more state skipped is added to specify the state of promises skipped by (fake) break, goto or a disposed context (However, the promise of which onfulfilled or onrejected has been called will not be skipped).

Resolve

Resolve is a process that may change the state of promise from pending to either fulfilled or rejected (not just the former state).

Terms

Promise

A promise in the documentation means the implementation of Promises/A+ in ThenFail.

Thenable/PromiseLike

A thenable or promise-like in the documentation means any other implementation that might act somewhat or exactly as we may expect a Promises/A or Promises/A+ implementation will.

Resolvable

A resolvable in the documentation means a thenable/promise-like or a normal value.

License

MIT License.