PromiseCascade

npm version Build Status Code Climate Test Coverage

Easy to use library for cascading promises.

Each promise in the cascade is an independent layer, deciding weather or not to call the next promise.

Workflow

This is a workflow example. Bear in mind that you could use PromiseCascade for any other purposes.

Workflow

Installation

Using NPM:

npm install promise-cascade --save

Using Yarn

yarn add promise-cascade

Using CDN

<script src="https://unpkg.com/promise-cascade/dist/PromiseCascade.js"></script>

Note: You may need a ES6 Promise polyfill to support older browsers.

API

Properties

Methods

Types

Examples

This examples are written in TypeScript. To use with ES6, just remove typings.

Pushing and Playing

import PromiseCascade, {PromiseFunction} from 'promise-cascade';

const addAwesomeness = async (times: number, callback: PromiseFunction) => {
    const callbackResponse = await callback();
    return 'Awesome'.repeat(times) + callbackResponse;
};

const capitalize = async (callback: PromiseFunction) => {
    const callbackResponse = await callback();
    return callbackResponse.toString().toUpperCase();
};

const fullName = async (name: string, surname: string) => `${name} ${surname}`; 

const cascade = new PromiseCascade();
const promise = cascade
    .push(addAwesomeness, 2)
    .push(capitalize)
    .push(fullName, 'John', 'Doe')
    .play();

promise.then((result) => {
   console.log(result); // 'Awesome Awesome JOHN DOE' 
});

Extending PromiseCascade

This example shows how to extend PromiseCascading for writing cleaner code.

The goal here is to establish two caching layers and a data fetching layer. This is a simplified version of Premiere JS caching workflow. For more details please check out the Premiere JS library.

import PromiseCascade, {PromiseFuntion} from 'promise-cascade';
import {Cache, Model} from 'premiere';
import axios from 'axios';

export default class CacheCascade<T> extends PromiseCascade {
    promisesCache: Cache<Promise<any>> = new Cache<Promise<any>>();
    objectsCache: Cache<T> = new Cache<T>();
    
    promiseCallback(name: string, callback: PromiseFunction): Promise<T> {
        const cached = this.promisesCache.get(name);
        if (cached) {
            return cached;
        }

        return this.promisesCache.set(name, callback());
    }

    promise(name: string): this {
        return this.push(this.promiseCallback.bind(this), name);
    }

    async objectCallback(key: any, callback: PromiseFunction): Promise<T> {
        const cached = this.objectsCache.get(key);
        if (cached) {
            return cached;
        }

        const result: T = await callback();
        return this.objectsCache.set(result.key, result);
    }

    object(key: any): this {
        return this.push(this.objectCallback.bind(this), key);
    }
}

const fetchModel = (url: string): async Promise<Model> => {
    const response = await axios.get(url);
    return Model.make(response.data);
};

const get(key: any): Promise<Model> => {
    const cascade = new CacheCascade<Model>();
    
    return cascade
        .promise('get/' + key) // Avoid making the same request before the first one has arrived
        .object('key') // Avoid redoing a request if this model is already cached
        .push(fetchModel, 'http://api.com/model/' + key) // Http request to the API
        .play();
};

get(1);

Resources

For more about how Promise works, check out Dave Atchley’s article

Articles

License

MIT