summaryrefslogtreecommitdiffstats
path: root/lib/utils/promise.js
blob: b0cfb34a91af28f06e87ada30f8bfc14a7913038 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
var Q = require('q');
var Immutable = require('immutable');

/**
    Reduce an array to a promise

    @param {Array|List} arr
    @param {Function(value, element, index)}
    @return {Promise<Mixed>}
*/
function reduce(arr, iter, base) {
    arr = Immutable.List(arr);

    return arr.reduce(function(prev, elem, i) {
        return prev.then(function(val) {
            return iter(val, elem, i);
        });
    }, Q(base));
}

/**
    Iterate over an array using an async iter

    @param {Array|List} arr
    @param {Function(value, element, index)}
    @return {Promise}
*/
function forEach(arr, iter) {
    return reduce(arr, function(val, el) {
        return iter(el);
    });
}

/**
    Transform an array

    @param {Array|List} arr
    @param {Function(value, element, index)}
    @return {Promise}
*/
function serie(arr, iter, base) {
    return reduce(arr, function(before, item, i) {
        return Q(iter(item, i))
        .then(function(r) {
            before.push(r);
            return before;
        });
    }, []);
}

/**
    Iter over an array and return first result (not null)

    @param {Array|List} arr
    @param {Function(element, index)}
    @return {Promise<Mixed>}
*/
function some(arr, iter) {
    arr = Immutable.List(arr);

    return arr.reduce(function(prev, elem, i) {
        return prev.then(function(val) {
            if (val) return val;

            return iter(elem, i);
        });
    }, Q());
}

/**
    Map an array using an async (promised) iterator

    @param {Array|List} arr
    @param {Function(element, index)}
    @return {Promise<List>}
*/
function map(arr, iter) {
    return reduce(arr, function(prev, entry, i) {
        return Q(iter(entry, i))
        .then(function(out) {
            prev.push(out);
            return prev;
        });
    }, []);
}

/**
    Wrap a fucntion in a promise

    @param {Function} func
    @return {Funciton}
*/
function wrap(func) {
    return function() {
        var args = Array.prototype.slice.call(arguments, 0);

        return Q()
        .then(function() {
            return func.apply(null, args);
        });
    };
}

module.exports = Q;
module.exports.forEach = forEach;
module.exports.reduce = reduce;
module.exports.map = map;
module.exports.serie = serie;
module.exports.some = some;
module.exports.wrapfn = wrap;