File: some-every.js

package info (click to toggle)
node-tad 3.1.1%2B~cs11.22.49-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 3,400 kB
  • sloc: javascript: 25,549; makefile: 6
file content (125 lines) | stat: -rw-r--r-- 3,029 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Promise aware Array's some

"use strict";

var assign          = require("es5-ext/object/assign")
  , isValue         = require("es5-ext/object/is-value")
  , ensureValue     = require("es5-ext/object/valid-value")
  , callable        = require("es5-ext/object/valid-callable")
  , toNaturalNumber = require("es5-ext/number/to-pos-integer")
  , deferred        = require("../deferred")
  , isPromise       = require("../is-promise")
  , assimilate      = require("../assimilate");

var call = Function.prototype.call, resolve = deferred.resolve;

module.exports = function (resolvent) {
	var Iterator = function (list, cb, context) {
		this.list = list;
		this.cb = cb;
		this.context = context;
		this.length = toNaturalNumber(list.length);

		while (this.current < this.length) {
			if (this.current in list) {
				assign(this, deferred());
				this.processCb = this.processCb.bind(this);
				this.processValue = this.processValue.bind(this);
				this.continue();
				return this.promise;
			}
			++this.current;
		}
		return resolve(!resolvent);
	};

	Iterator.prototype = {
		current: 0,
		state: false,
		continue: function () {
			var result;
			while (!this.state) {
				result = this.process();
				if (this.state !== "cb") break;
				result = this.processCb(result);
				if (this.state !== "value") break;
				this.processValue(result);
			}
		},
		process: function () {
			var value = assimilate(this.list[this.current]);
			if (isPromise(value)) {
				if (!value.resolved) {
					value.done(
						function (result) {
							result = this.processCb(result);
							if (this.state !== "value") return;
							this.processValue(result);
							if (!this.state) this.continue();
						}.bind(this),
						this.reject
					);
					return null;
				}
				if (value.failed) {
					this.reject(value.value);
					return null;
				}
				value = value.value;
			}
			this.state = "cb";
			return value;
		},
		processCb: function (value) {
			if (this.cb) {
				try {
					value = call.call(this.cb, this.context, value, this.current, this.list);
				} catch (e) {
					this.reject(e);
					return null;
				}
				value = assimilate(value);
				if (isPromise(value)) {
					if (!value.resolved) {
						value.done(
							function (result) {
								this.state = "value";
								this.processValue(result);
								if (!this.state) this.continue();
							}.bind(this),
							this.reject
						);
						return null;
					}
					if (value.failed) {
						this.reject(value.value);
						return null;
					}
					value = value.value;
				}
			}
			this.state = "value";
			return value;
		},
		processValue: function (value) {
			if (Boolean(value) === resolvent) {
				this.resolve(resolvent);
				return;
			}
			while (++this.current < this.length) {
				if (this.current in this.list) {
					this.state = false;
					return;
				}
			}
			this.resolve(!resolvent);
		}
	};

	return function (cb/*, thisArg*/) {
		ensureValue(this);
		if (isValue(cb)) callable(cb);

		return new Iterator(this, cb, arguments[1]);
	};
};