prray
Version:
'Promisified' Array, it compatible with the original Array but comes with async versions of native Array methods, such as `mapAsync`, `filterAsync`, `reduceAsync`, `sortAsync`, `findAsync`, `findIndexAsync`, `everyAsync`, `someAsync`, `forEachAsync`...
306 lines (305 loc) • 9.59 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
function mapAsync(arr, func, opts = { concurrency: Infinity }) {
return __awaiter(this, void 0, void 0, function* () {
const result = [];
yield loop(arr, (value, ix) => __awaiter(this, void 0, void 0, function* () { return (result[ix] = yield func(value, ix, arr)); }), opts);
return result;
});
}
exports.mapAsync = mapAsync;
function map(prr, func) {
const result = [];
for (let ix = 0; ix < prr.length; ix++) {
result.push(func(prr[ix], ix, prr));
}
return result;
}
exports.map = map;
function filterAsync(arr, func, opts = { concurrency: Infinity }) {
return __awaiter(this, void 0, void 0, function* () {
const result = [];
yield loop(arr, (value, ix) => __awaiter(this, void 0, void 0, function* () { return ((yield func(value, ix, arr)) ? result.push(value) : null); }), opts);
return result;
});
}
exports.filterAsync = filterAsync;
function filter(prr, func) {
const result = [];
for (let ix = 0; ix < prr.length; ix++) {
const value = prr[ix];
if (func(value, ix, prr)) {
result.push(value);
}
}
return result;
}
exports.filter = filter;
function reduceAsync(prr, func, initialValue) {
return __awaiter(this, void 0, void 0, function* () {
if (prr.length === 0) {
if (initialValue === undefined) {
throw TypeError('Reduce of empty array with no initial value');
}
else {
return initialValue;
}
}
let pre = initialValue;
let ix = 0;
if (initialValue === undefined) {
pre = prr[0];
ix = 1;
}
for (ix; ix < prr.length; ix++) {
const current = prr[ix];
pre = yield func(pre, current, ix, prr);
}
return pre;
});
}
exports.reduceAsync = reduceAsync;
function reduce(prr, func, initialValue) {
if (prr.length === 0) {
if (initialValue === undefined) {
throw TypeError('Reduce of empty array with no initial value');
}
else {
return initialValue;
}
}
let pre = initialValue;
let ix = 0;
if (initialValue === undefined) {
pre = prr[0];
ix = 1;
}
for (ix; ix < prr.length; ix++) {
const current = prr[ix];
pre = func(pre, current, ix, prr);
}
return pre;
}
exports.reduce = reduce;
function reduceRightAsync(prr, func, initialValue) {
return __awaiter(this, void 0, void 0, function* () {
if (prr.length === 0) {
if (initialValue === undefined) {
throw TypeError('Reduce of empty array with no initial value');
}
else {
return initialValue;
}
}
let pre = initialValue;
let ix = prr.length - 1;
if (initialValue === undefined) {
pre = prr[prr.length - 1];
ix = prr.length - 2;
}
for (ix; ix >= 0; ix--) {
const current = prr[ix];
pre = yield func(pre, current, ix, prr);
}
return pre;
});
}
exports.reduceRightAsync = reduceRightAsync;
function reduceRight(prr, func, initialValue) {
if (prr.length === 0) {
if (initialValue === undefined) {
throw TypeError('Reduce of empty array with no initial value');
}
else {
return initialValue;
}
}
let pre = initialValue;
let ix = prr.length - 1;
if (initialValue === undefined) {
pre = prr[prr.length - 1];
ix = prr.length - 2;
}
for (ix; ix >= 0; ix--) {
const current = prr[ix];
pre = func(pre, current, ix, prr);
}
return pre;
}
exports.reduceRight = reduceRight;
function findIndexAsync(arr, func) {
return __awaiter(this, void 0, void 0, function* () {
let result = -1;
yield loop(arr, (value, ix, _, breakLoop) => __awaiter(this, void 0, void 0, function* () {
if (yield func(value, ix, arr)) {
result = ix;
breakLoop();
}
}), {});
return result;
});
}
exports.findIndexAsync = findIndexAsync;
function findIndex(prr, func) {
const length = prr.length;
for (let ix = 0; ix < length; ix++) {
if (func(prr[ix], ix, prr)) {
return ix;
}
}
return -1;
}
exports.findIndex = findIndex;
function findAsync(arr, func) {
return __awaiter(this, void 0, void 0, function* () {
let result;
yield loop(arr, (value, ix, _, breakLoop) => __awaiter(this, void 0, void 0, function* () {
if (yield func(value, ix, arr)) {
result = value;
breakLoop();
}
}), {});
return result;
});
}
exports.findAsync = findAsync;
function find(prr, func) {
const length = prr.length;
for (let ix = 0; ix < length; ix++) {
if (func(prr[ix], ix, prr)) {
return prr[ix];
}
}
return undefined;
}
exports.find = find;
function everyAsync(prr, func, opts = { concurrency: Infinity }) {
return __awaiter(this, void 0, void 0, function* () {
let result = true;
yield loop(prr, (value, ix, _, breakLoop) => __awaiter(this, void 0, void 0, function* () {
if (!(yield func(value, ix, prr))) {
result = false;
breakLoop();
}
}), opts);
return result;
});
}
exports.everyAsync = everyAsync;
function every(prr, func) {
for (let ix = 0; ix < prr.length; ix++) {
if (!func(prr[ix], ix, prr)) {
return false;
}
}
return true;
}
exports.every = every;
function someAsync(prr, func, opts = { concurrency: Infinity }) {
return __awaiter(this, void 0, void 0, function* () {
let result = false;
yield loop(prr, (value, ix, _, breakLoop) => __awaiter(this, void 0, void 0, function* () {
if (yield func(value, ix, prr)) {
result = true;
breakLoop();
}
}), opts);
return result;
});
}
exports.someAsync = someAsync;
function some(prr, func) {
for (let ix = 0; ix < prr.length; ix++) {
if (func(prr[ix], ix, prr)) {
return true;
}
}
return false;
}
exports.some = some;
function sortAsync(arr, func) {
return __awaiter(this, void 0, void 0, function* () {
if (!func) {
return arr.sort();
}
if (arr.length < 2) {
return arr;
}
// 插入排序
for (let i = 1; i < arr.length; i++) {
for (let j = 0; j < i; j++) {
if ((yield func(arr[i], arr[j])) < 0) {
arr.splice(j, 0, arr[i]);
arr.splice(i + 1, 1);
break;
}
}
}
return arr;
});
}
exports.sortAsync = sortAsync;
function forEachAsync(prr, func, opts = { concurrency: Infinity }) {
return __awaiter(this, void 0, void 0, function* () {
yield loop(prr, (value, ix) => __awaiter(this, void 0, void 0, function* () { return func(value, ix, prr); }), opts);
return;
});
}
exports.forEachAsync = forEachAsync;
function forEach(prr, func) {
for (let ix = 0; ix < prr.length; ix++) {
func(prr[ix], ix, prr);
}
return;
}
exports.forEach = forEach;
function loop(array, func, { concurrency = Infinity }) {
// FEATURE: options { concurrency, timeout, retries, defaults, fallback }
if (array.length <= concurrency) {
const promises = array.map((v, ix) => func(v, ix, array, () => null));
return Promise.all(promises);
}
return new Promise((resolve, reject) => {
const length = array.length;
if (length === 0) {
resolve();
}
let isEnding = false;
let currentIndex = 0;
let workingNum = Math.min(concurrency, length);
const breakLoop = () => {
isEnding = true;
resolve();
};
const woker = () => __awaiter(this, void 0, void 0, function* () {
while (!isEnding && currentIndex < length) {
const ix = currentIndex++;
try {
yield func(array[ix], ix, array, breakLoop);
}
catch (error) {
isEnding = true;
reject(error);
return;
}
}
workingNum--;
if (workingNum === 0) {
resolve();
}
});
for (let i = 0; i < Math.min(concurrency, length); i++) {
woker();
}
});
}
exports.loop = loop;