0.1.0 • Published 5 years ago

undertake v0.1.0

Weekly downloads
3
License
MIT
Repository
github
Last release
5 years ago

undertake

Another choice beyond co.

total downloads of undertake undertake's License latest version of undertake

If links in this document not avaiable, please access [README on GitHub](./README.md) directly.

Description

undertake is incubated from jinang/co. It is something like well-known co. It just offers another choice.

Table of Contents

Get Started

const undertake = require('undertake');

// A generator function.
function* success() {
    // yield promise.
    let a = yield Promise.resolve('A');

    // yield thunkified function.
    let b = yield callback => {
        setTimeout(() => callback(null, 'B'), 100);
    };

    let c = yield subtask(1);
    // c equals 3

    // Traverse an array.
    let d = 0;
    yield undertake.each([1,2,3], function*(num, index) {
        d += yield Promise.resolve(num);
    });
    // d equals 6

    // Traverse an array and return a mapped one.
    let e = yield undertake.map([1,2,3], function*(num, index) {
        return yield Promise.resolve(num * 2);
    });
    // e equals [2,4,6]

    let F = function(num_1, num_2, callback) {
        setTimeout(() => callback(null, num_1 * num_2), 100);
    };
    let f1 = yield undertake.calling(F, null, 4, 6);
    // f1 equals 24
    let f2 = yield undertake.applying(F, null, [ 4, 6 ]);
    // f2 equals 24

    return a + b + c + d;
}

function* subtask(n) {
    let m = yield Promise.resolve(n);
    let n = yield Promise.resolve(n+1);
    return m + n;
}

// When no callback passed in, an instance of Promise will be returned.
undertake(success).then(ret => {
    // ret equals "AB36"
});

// A triditional callback is acceptable.
undertake(success, function(err, data) {
    // err equals null
    // data euqals "AB36"
});
// RETURN undefined

// If callback is also a generator function, an instance of Promise will be returned.
undertake(success, function*(err, data) {
    let f = yield subtask(4);
    return data + f;
}).then(ret => {
    // ret equals "AB369";
});

// Create a new function which will accept the same paramenters as the generator function do,
// and return an instance of Promise on being invoked.
let fn = undertake.sync(subtask);
fn(2).then(ret => {
    // ret equals 5
});

API

  • Promise undertake(GeneratorFunction fn)
    Something like co.

  • Promise undertake(GeneratorFunction fn , GeneratorFunction callback, boolean compatible )
    Successively execute generator functions fn and callback.
    If compatible is true, returned value which is instance of Error will be regarded as normal value. Otherwise and by default, such returned value will trigger rejection.

  • void undertake(GeneratorFunction fn, Function callback , boolean compatible )
    Execute the generator function fn, then invoke callback.

  • Promise undertake.applying(Function fn, Object this_value, Array args)
    Invoke fn and return an instance of Promise.
    Function fn SHOULD accept a standard callback function as the last argument. Developer SHOULD NOT put a callback in args, it will be automatically appended when fn is really invoked.
    This util is designed to make things easy to yield a traditional asynchronised function.

  • Promise undertake.calling(Function fn, Object this_value, Any arg_0, ...)
    Invoke fn and return an instance of Promise.

  • Promise undertake.easy(GeneratorFunction fn)
    See undertake vs. undertake.easy.

  • Promise(undefined) undertake.each(Array arr, GeneratorFunction iterator)
    For each item of arr, execute the generator function iterator with the item as the only argument.

  • Promise(Array) undertake.map(Array arr, GeneratorFunction iterator)
    Return an array of Promise instances. Each promise will carry the data returned by the corresponding generator function.

  • boolean undertake.isGenerator(any foo) A util function.

  • boolean undertake.isGeneratorFunction(any foo)
    A util function.

  • Function undertake.sync(GeneratorFunction fn , Function callback)
    Wrap a generator function. Without callback, the new function will return an instance of Promise on being invoked. Otherwise, callback() will be invoked finally when the new function is invoked and completed.

  • Function undertake.async(GeneratorFunction fn , number callbackIndex)
    Wrap a generator function. The new function will return an instance of Promise on being invoked without a callback function, or callback() will be invoked finally. Parameter callbackIndex will indicate the position of callback. By default, the last argument with type of 'function' will be regarded as the callback function.

If callback(err, data) exists, what returned by the generator function will become data and what throwed will become err.

undertake vs. undertake.easy

For undertake, operator yield expects a promise, generator function or thunkify function. If something following yield is not expected, an error will be thrown.

For undertake.easy, anything is allowed to follow yield operator. If it is not an instance of Promise or Function, itself will be returned by yield. E.g.

// A generator function.
function* main() {
    let a = yield Promise.resolve('A');
    // `a` now equals 'A'.

    let b = yield 'B';
    // `b` now equals 'B';

    return a + b;
}

// Error: operator `yield` expects a promise, generator function or thunkify function
let p0 = undertake(main);

// It's OK.
let p1 = undertake.easy(main);

// It's OK. As same as p1.
let p2 = undertake(main, null, true);

undertake.sync vs. undertake.async

undertake.sync() and undertake.async() are used to create (or so-called "wrap") a generator function and return a new normal one. They two are actually identical when no "callback()" occurs.

function* main() {
    return yield Promise.resolve('A');
}

function callback(err, data) {
    console.log(data.toLowerCase());
}

// A new function is created. "main()" does not run now.
const f0 = undertake.sync(main);
// Promise(A) returned.
f0();
// Promise(A) returned. "callback" is ignored.
f0(callback);  

// Both "main()" and "callback()" do not run now.
const f1 = undertake.sync(main, callback);
// Nothing returned. "a" is printed.
f1();

// f2 is the same as f0.
const f2 = undertake.async(main);
// Promise(A) returned.
f2();
// Nothing returned. "a" is printed. Here, the last argument is regarded as "callback" if it is a function.
f2(callback);

// The first (index 0) argument passed to f3 will be regarded as "callback".
const f3 = undertake.async(main, 0);
// Promise(A) returned.
f3();
// Nothing returned. "a" is printed.
f3(callback);

Links