UNPKG

promise-useful-utils

Version:
281 lines (234 loc) 6.79 kB
'use strict'; var _Promise = require('babel-runtime/core-js/promise')['default']; var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; Object.defineProperty(exports, '__esModule', { value: true }); exports.props = props; exports.settle = settle; exports.some = some; exports.map = map; exports.reduce = reduce; exports.filter = filter; exports.each = each; var _errors = require('./errors'); /** * @param {Object} * @return {Promise.<Object>} */ function props(obj) { return _Promise.resolve().then(function () { var type = typeof obj; if (!(!!obj && type === 'object')) { throw new TypeError('cannot await properties of a non-object'); } var keys = _Object$keys(obj); return _Promise.all(keys.map(function (key) { return obj[key]; })).then(function (values) { var result = {}; for (var index = 0; index < values.length; ++index) { result[keys[index]] = values[index]; } return result; }); }); } /** * @param {Array.<*>} args * @return {Promise.<Array.<*>>} */ function settle(args) { if (!Array.isArray(args)) { return _Promise.reject(new TypeError('expecting an array')); } if (args.length === 0) { return _Promise.resolve([]); } return new _Promise(function (resolve) { var ready = 0; var values = new Array(args.length); var _loop = function (index) { _Promise.resolve(args[index]).then(function (value) { values[index] = { value: value }; }, function (err) { values[index] = { reason: err }; }).then(function () { ready += 1; if (ready === args.length) { resolve(values); } }); }; for (var index = 0; index < args.length; ++index) { _loop(index); } }); } /** * @param {Array.<*>} args * @param {number} [count=1] * @return {Promise.<Array.<*>>} */ function some(args, count) { if (!Array.isArray(args)) { return _Promise.reject(new TypeError('expecting an array')); } count = parseInt(count, 10); if (isNaN(count) || count < 0) { return _Promise.reject(new TypeError('expecting a positive integer')); } if (count === 0) { return _Promise.resolve([]); } if (count > args.length) { return _Promise.reject(new RangeError('Input array must contain at least ' + count + ' items but contains only ' + args.length + ' items')); } var values = []; var reasons = []; return new _Promise(function (resolve, reject) { for (var index = 0; index < args.length; ++index) { args[index].then(function (value) { values.push(value); if (values.length === count) { resolve(values); } }, function (err) { reasons.push(err); if (reasons.length + count > args.length) { err = new _errors.AggregateError(); err.reasons = reasons; reject(err); } }); } }); } /** * @param {Array.<*>} args * @param {function} mapper * @param {Object} [options] * @param {number} [options.concurrency = Infinity] * @return {Promise.<Array.<*>>} */ function map(args, mapper) { var options = arguments.length <= 2 || arguments[2] === undefined ? { concurrency: Infinity } : arguments[2]; if (!Array.isArray(args)) { return _Promise.reject(new TypeError('expecting an array')); } if (args.length === 0) { return _Promise.resolve([]); } if (typeof mapper !== 'function') { return _Promise.reject(new TypeError('fn must be a function')); } var concurrency = Object(options).concurrency; if (concurrency === Infinity) { concurrency = args.length; } concurrency = parseInt(concurrency, 10); if (isNaN(concurrency) || concurrency < 0) { return _Promise.reject(new TypeError('expecting a positive integer')); } if (concurrency > args.length) { return _Promise.reject(new RangeError('Input array must contain at least ' + concurrency + ' items but contains only ' + args.length + ' items')); } return new _Promise(function (resolve, reject) { var ready = 0; var values = new Array(args.length); var isRejected = false; function next(index) { if (index >= args.length || isRejected) { if (ready === args.length) { resolve(values); } return; } _Promise.resolve(args[index]).then(function (item) { return mapper(item, index, args); }).then(function (value) { ready += 1; values[index] = value; next(index + concurrency); }, function (err) { isRejected = true; reject(err); }); } for (var index = 0; index < concurrency; ++index) { next(index); } }); } /** * @param {Array.<*>} args * @param {function} reducer * @param {*} [initialValue] * @return {Promise.<*>} */ function reduce(args, reducer, initialValue) { if (!Array.isArray(args)) { return _Promise.reject(new TypeError('expecting an array')); } if (typeof reducer !== 'function') { return _Promise.reject(new TypeError('fn must be a function')); } return new _Promise(function (resolve, reject) { var total = initialValue; function next(index) { if (index === args.length) { return resolve(total); } _Promise.resolve(args[index]).then(function (item) { return reducer(total, item, index, args); }).then(function (value) { total = value; next(index + 1); }, function (err) { reject(err); }); } next(0); }); } /** * @param {Array.<*>} args * @param {function} filterer * @param {Object} [options] * @param {number} [options.concurrency = Infinity] * @return {Promise.<Array.<*>>} */ function filter(args, filterer) { var options = arguments.length <= 2 || arguments[2] === undefined ? { concurrency: Infinity } : arguments[2]; if (typeof filterer !== 'function') { return _Promise.reject(new TypeError('fn must be a function')); } return map(args, function (item, index, args) { return _Promise.resolve(filterer(item, index, args)).then(function (isValid) { return [isValid, item]; }); }, options).then(function (items) { return items.filter(function (item) { return item[0]; }).map(function (item) { return item[1]; }); }); } /** * @param {Array.<*>} args * @param {function} iterator * @return {Promise.<Array.<*>>} */ function each(args, iterator) { if (typeof iterator !== 'function') { return _Promise.reject(new TypeError('fn must be a function')); } var values = []; return reduce(args, function (_, item, index) { values.push(item); return iterator(item, index, args); }).then(function () { return values; }); }