promise.extra
Version:
series, waterfall and more with vanilla es promise/thenable.
115 lines (93 loc) • 2.86 kB
JavaScript
;
var isPositive = function isPositive(x) {
return x;
};
var isNegative = function isNegative(x) {
return !x;
};
var defaultRunner = function defaultRunner(prev, v) {
return v;
};
var factory = function factory(p) {
function reduce(list, reducer, init) {
var _this = this;
var run = function run(i) {
return function (prev) {
return reducer.call(_this, prev, list[i], i, list);
};
}; // Do not save `list.length`,
// because we allow user to modify the array `list`
var next = function next(i, prev) {
return i < list.length ? list.hasOwnProperty(i) ? next(i + 1, prev.then(run(i))) : next(i + 1, prev) : prev;
};
return next(0, p.resolve(init));
}
function series(list) {
var _this2 = this;
var runner = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultRunner;
return reduce.call(this, list, function (prev, factory, i, list) {
return p.resolve(runner.call(_this2, prev, factory, i, list)).then(function (result) {
prev[i] = result;
return prev;
});
}, []);
}
function waterfall(list, init) {
var runner = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultRunner;
return reduce.call(this, list, runner, init);
}
function findIndex(list, matcher) {
var _this3 = this;
var runner = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultRunner;
return reduce.call(this, list, function (prev, factory, i, list) {
if (prev !== -1) {
return prev;
}
return p.resolve(runner.call(_this3, prev, factory, i, list)).then(function (result) {
return matcher.call(_this3, result, i, list);
}).then(function (matched) {
return matched ? i : -1;
});
}, -1);
}
function indexOf(list, value, runner) {
return findIndex.call(this, list, function (result) {
return result === value;
}, runner);
}
function some(list, runner) {
return findIndex.call(this, list, isPositive, runner).then(function (index) {
return index !== -1 ? true : false;
});
}
function every(list, runner) {
return findIndex.call(this, list, isNegative, runner).then(function (index) {
return index === -1 ? true : false;
});
}
function find(list, matcher, runner) {
var found;
return findIndex(list, function (result) {
return p.resolve(matcher.apply(this, arguments)).then(function (matched) {
if (matched) {
found = result;
}
return matched;
});
}, runner).then(function () {
return found;
});
}
return {
reduce,
series,
waterfall,
findIndex,
indexOf,
some,
every,
find
};
};
module.exports = factory(Promise);
module.exports.factory = factory;