1 | var anObject = require('../internals/an-object');
|
---|
2 | var isArrayIteratorMethod = require('../internals/is-array-iterator-method');
|
---|
3 | var toLength = require('../internals/to-length');
|
---|
4 | var bind = require('../internals/function-bind-context');
|
---|
5 | var getIteratorMethod = require('../internals/get-iterator-method');
|
---|
6 | var iteratorClose = require('../internals/iterator-close');
|
---|
7 |
|
---|
8 | var Result = function (stopped, result) {
|
---|
9 | this.stopped = stopped;
|
---|
10 | this.result = result;
|
---|
11 | };
|
---|
12 |
|
---|
13 | module.exports = function (iterable, unboundFunction, options) {
|
---|
14 | var that = options && options.that;
|
---|
15 | var AS_ENTRIES = !!(options && options.AS_ENTRIES);
|
---|
16 | var IS_ITERATOR = !!(options && options.IS_ITERATOR);
|
---|
17 | var INTERRUPTED = !!(options && options.INTERRUPTED);
|
---|
18 | var fn = bind(unboundFunction, that, 1 + AS_ENTRIES + INTERRUPTED);
|
---|
19 | var iterator, iterFn, index, length, result, next, step;
|
---|
20 |
|
---|
21 | var stop = function (condition) {
|
---|
22 | if (iterator) iteratorClose(iterator);
|
---|
23 | return new Result(true, condition);
|
---|
24 | };
|
---|
25 |
|
---|
26 | var callFn = function (value) {
|
---|
27 | if (AS_ENTRIES) {
|
---|
28 | anObject(value);
|
---|
29 | return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]);
|
---|
30 | } return INTERRUPTED ? fn(value, stop) : fn(value);
|
---|
31 | };
|
---|
32 |
|
---|
33 | if (IS_ITERATOR) {
|
---|
34 | iterator = iterable;
|
---|
35 | } else {
|
---|
36 | iterFn = getIteratorMethod(iterable);
|
---|
37 | if (typeof iterFn != 'function') throw TypeError('Target is not iterable');
|
---|
38 | // optimisation for array iterators
|
---|
39 | if (isArrayIteratorMethod(iterFn)) {
|
---|
40 | for (index = 0, length = toLength(iterable.length); length > index; index++) {
|
---|
41 | result = callFn(iterable[index]);
|
---|
42 | if (result && result instanceof Result) return result;
|
---|
43 | } return new Result(false);
|
---|
44 | }
|
---|
45 | iterator = iterFn.call(iterable);
|
---|
46 | }
|
---|
47 |
|
---|
48 | next = iterator.next;
|
---|
49 | while (!(step = next.call(iterator)).done) {
|
---|
50 | try {
|
---|
51 | result = callFn(step.value);
|
---|
52 | } catch (error) {
|
---|
53 | iteratorClose(iterator);
|
---|
54 | throw error;
|
---|
55 | }
|
---|
56 | if (typeof result == 'object' && result && result instanceof Result) return result;
|
---|
57 | } return new Result(false);
|
---|
58 | };
|
---|