prray
Version:
'Promisified' Array, comes with async method supports(such as mapAsync). And it is compatible with normal array.
209 lines (208 loc) • 6.71 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
function map(arr, func) {
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)); }), {});
return result;
});
}
exports.map = map;
function filter(arr, func) {
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); }), {});
return result;
});
}
exports.filter = filter;
function reduce(arr, func, initialValue) {
return __awaiter(this, void 0, void 0, function* () {
let pre = initialValue;
let ix = 0;
if (initialValue === undefined) {
pre = arr[0];
ix = 1;
}
for (ix; ix < arr.length; ix++) {
const current = arr[ix];
pre = yield func(pre, current, ix, arr);
}
return pre;
});
}
exports.reduce = reduce;
function reduceRight(arr, func, initialValue) {
return __awaiter(this, void 0, void 0, function* () {
let pre = initialValue;
let ix = arr.length - 1;
if (initialValue === undefined) {
pre = arr[arr.length - 1];
ix = arr.length - 2;
}
for (ix; ix >= 0; ix--) {
const current = arr[ix];
pre = yield func(pre, current, ix, arr);
}
return pre;
});
}
exports.reduceRight = reduceRight;
function findIndex(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.findIndex = findIndex;
function find(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.find = find;
function every(arr, func) {
return __awaiter(this, void 0, void 0, function* () {
let result = true;
yield loop(arr, (value, ix, _, breakLoop) => __awaiter(this, void 0, void 0, function* () {
if (!(yield func(value, ix, arr))) {
result = false;
breakLoop();
}
}), {});
return result;
});
}
exports.every = every;
function some(arr, func) {
return __awaiter(this, void 0, void 0, function* () {
let result = false;
yield loop(arr, (value, ix, _, breakLoop) => __awaiter(this, void 0, void 0, function* () {
if (yield func(value, ix, arr)) {
result = true;
breakLoop();
}
}), {});
return result;
});
}
exports.some = some;
function sort(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.sort = sort;
function forEach(arr, func) {
return __awaiter(this, void 0, void 0, function* () {
return loop(arr, (value, ix) => __awaiter(this, void 0, void 0, function* () { return func(value, ix, arr); }), {});
});
}
exports.forEach = forEach;
function slice(arr, start = 0, end = Infinity) {
if (start === 0 && end === Infinity) {
return arr;
}
if (start > arr.length) {
start = arr.length;
}
if (start < -arr.length) {
start = -arr.length;
}
if (end > arr.length) {
end = arr.length;
}
if (end < -arr.length) {
end = -arr.length;
}
if (start < 0) {
start = arr.length + start;
}
if (end < 0) {
end = arr.length + end;
}
const result = [];
for (let ix = start; ix < end; ix++) {
result.push(arr[ix]);
}
return result;
}
exports.slice = slice;
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;