196 lines
5.0 KiB
JavaScript
196 lines
5.0 KiB
JavaScript
'use strict';
|
|
|
|
exports.isIterable = isIterable;
|
|
exports.isArrayLike = isArrayLike;
|
|
exports.isCollection = isCollection;
|
|
exports.getIterator = getIterator;
|
|
exports.getIteratorMethod = getIteratorMethod;
|
|
exports.createIterator = createIterator;
|
|
exports.forEach = forEach;
|
|
exports.isAsyncIterable = isAsyncIterable;
|
|
exports.getAsyncIterator = getAsyncIterator;
|
|
exports.getAsyncIteratorMethod = getAsyncIteratorMethod;
|
|
exports.createAsyncIterator = createAsyncIterator;
|
|
exports.forAwaitEach = forAwaitEach;
|
|
|
|
var SYMBOL = typeof Symbol === 'function' ? Symbol : void 0;
|
|
|
|
var SYMBOL_ITERATOR = SYMBOL && SYMBOL.iterator;
|
|
|
|
var $$iterator = exports.$$iterator = SYMBOL_ITERATOR || '@@iterator';
|
|
|
|
function isIterable(obj) {
|
|
return !!getIteratorMethod(obj);
|
|
}
|
|
|
|
function isArrayLike(obj) {
|
|
var length = obj != null && obj.length;
|
|
return typeof length === 'number' && length >= 0 && length % 1 === 0;
|
|
}
|
|
|
|
function isCollection(obj) {
|
|
return Object(obj) === obj && (isArrayLike(obj) || isIterable(obj));
|
|
}
|
|
|
|
function getIterator(iterable) {
|
|
var method = getIteratorMethod(iterable);
|
|
if (method) {
|
|
return method.call(iterable);
|
|
}
|
|
}
|
|
|
|
function getIteratorMethod(iterable) {
|
|
if (iterable != null) {
|
|
var method = SYMBOL_ITERATOR && iterable[SYMBOL_ITERATOR] || iterable['@@iterator'];
|
|
if (typeof method === 'function') {
|
|
return method;
|
|
}
|
|
}
|
|
}
|
|
|
|
function createIterator(collection) {
|
|
if (collection != null) {
|
|
var iterator = getIterator(collection);
|
|
if (iterator) {
|
|
return iterator;
|
|
}
|
|
if (isArrayLike(collection)) {
|
|
return new ArrayLikeIterator(collection);
|
|
}
|
|
}
|
|
}
|
|
|
|
function ArrayLikeIterator(obj) {
|
|
this._o = obj;
|
|
this._i = 0;
|
|
}
|
|
|
|
ArrayLikeIterator.prototype[$$iterator] = function () {
|
|
return this;
|
|
};
|
|
|
|
ArrayLikeIterator.prototype.next = function () {
|
|
if (this._o === void 0 || this._i >= this._o.length) {
|
|
this._o = void 0;
|
|
return { value: void 0, done: true };
|
|
}
|
|
return { value: this._o[this._i++], done: false };
|
|
};
|
|
|
|
function forEach(collection, callback, thisArg) {
|
|
if (collection != null) {
|
|
if (typeof collection.forEach === 'function') {
|
|
return collection.forEach(callback, thisArg);
|
|
}
|
|
var i = 0;
|
|
var iterator = getIterator(collection);
|
|
if (iterator) {
|
|
var step;
|
|
while (!(step = iterator.next()).done) {
|
|
callback.call(thisArg, step.value, i++, collection);
|
|
|
|
if (i > 9999999) {
|
|
throw new TypeError('Near-infinite iteration.');
|
|
}
|
|
}
|
|
} else if (isArrayLike(collection)) {
|
|
for (; i < collection.length; i++) {
|
|
if (collection.hasOwnProperty(i)) {
|
|
callback.call(thisArg, collection[i], i, collection);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var SYMBOL_ASYNC_ITERATOR = SYMBOL && SYMBOL.asyncIterator;
|
|
|
|
var $$asyncIterator = exports.$$asyncIterator = SYMBOL_ASYNC_ITERATOR || '@@asyncIterator';
|
|
|
|
function isAsyncIterable(obj) {
|
|
return !!getAsyncIteratorMethod(obj);
|
|
}
|
|
|
|
function getAsyncIterator(asyncIterable) {
|
|
var method = getAsyncIteratorMethod(asyncIterable);
|
|
if (method) {
|
|
return method.call(asyncIterable);
|
|
}
|
|
}
|
|
|
|
function getAsyncIteratorMethod(asyncIterable) {
|
|
if (asyncIterable != null) {
|
|
var method = SYMBOL_ASYNC_ITERATOR && asyncIterable[SYMBOL_ASYNC_ITERATOR] || asyncIterable['@@asyncIterator'];
|
|
if (typeof method === 'function') {
|
|
return method;
|
|
}
|
|
}
|
|
}
|
|
|
|
function createAsyncIterator(source) {
|
|
if (source != null) {
|
|
var asyncIterator = getAsyncIterator(source);
|
|
if (asyncIterator) {
|
|
return asyncIterator;
|
|
}
|
|
var iterator = createIterator(source);
|
|
if (iterator) {
|
|
return new AsyncFromSyncIterator(iterator);
|
|
}
|
|
}
|
|
}
|
|
|
|
function AsyncFromSyncIterator(iterator) {
|
|
this._i = iterator;
|
|
}
|
|
|
|
AsyncFromSyncIterator.prototype[$$asyncIterator] = function () {
|
|
return this;
|
|
};
|
|
|
|
AsyncFromSyncIterator.prototype.next = function (value) {
|
|
return unwrapAsyncFromSync(this._i, 'next', value);
|
|
};
|
|
|
|
AsyncFromSyncIterator.prototype.return = function (value) {
|
|
return this._i.return ? unwrapAsyncFromSync(this._i, 'return', value) : Promise.resolve({ value: value, done: true });
|
|
};
|
|
|
|
AsyncFromSyncIterator.prototype.throw = function (value) {
|
|
return this._i.throw ? unwrapAsyncFromSync(this._i, 'throw', value) : Promise.reject(value);
|
|
};
|
|
|
|
function unwrapAsyncFromSync(iterator, fn, value) {
|
|
var step;
|
|
return new Promise(function (resolve) {
|
|
step = iterator[fn](value);
|
|
resolve(step.value);
|
|
}).then(function (value) {
|
|
return { value: value, done: step.done };
|
|
});
|
|
}
|
|
|
|
function forAwaitEach(source, callback, thisArg) {
|
|
var asyncIterator = createAsyncIterator(source);
|
|
if (asyncIterator) {
|
|
var i = 0;
|
|
return new Promise(function (resolve, reject) {
|
|
function next() {
|
|
asyncIterator.next().then(function (step) {
|
|
if (!step.done) {
|
|
Promise.resolve(callback.call(thisArg, step.value, i++, source)).then(next).catch(reject);
|
|
} else {
|
|
resolve();
|
|
}
|
|
|
|
return null;
|
|
}).catch(reject);
|
|
|
|
return null;
|
|
}
|
|
next();
|
|
});
|
|
}
|
|
}
|
|
|