Commits

Daniel Roberts committed 4e940f3 Draft

Initial commit.

  • Participants

Comments (0)

Files changed (1)

+if (typeof DeferredCollection === "undefined") {
+    DeferredCollection = (function() { 
+        // Core functionality
+        function PromisedCollection(deferred) {
+            this.deferred = deferred;
+            this.forEachObservers = [];
+            this.rejectObservers = [];
+            this.resolveObservers = [];
+        }
+        PromisedCollection.prototype.forEach = function forEach(f) {
+            for (var i = 0; i < this.deferred.length; i++) {
+                f(this.deferred[i], i);
+            }
+            this.forEachObservers.push(f);
+        }
+        PromisedCollection.prototype.then = function then(resolve, reject) {
+            if (this.deferred.state === "unfulfilled") {
+                if (typeof resolve !== "undefined") {
+                    this.resolveObservers.push(resolve);
+                }
+                if (typeof reject !== "undefined") {
+                    this.rejectObservers.push(reject);
+                }
+            } else if (this.deferred.state === "resolved" && typeof resolve !== "undefined") {
+                resolve(this);
+            } else if (this.deferred.state === "rejected" && typeof reject !== "undefined") {
+                reject(this.error);
+            }
+        }
+        function DeferredCollection(data) {
+            if (typeof data !== "undefined") {
+                this.data = data;
+                this.state = "resolved";
+            } else {
+                this.data = [];
+            }
+
+            this.promise = new PromisedCollection(this);
+        }
+        DeferredCollection.prototype.emit = function emit(element) {
+            for (var i = 0; i < promise.forEachObservers.length; i++) {
+                promise.forEachObservers[i](element, i);
+            }
+            this.data.push(element);
+        }
+        DeferredCollection.prototype.emitMany = function emitMany(elements) {
+            // Support non-array iterables
+            if (typeof elements.forEach !== "undefined") {
+                var collection = this;
+                elements.forEach(function (element) {
+                    collection.emit(element);
+                });
+            } else {
+                for (var i = 0; i < elements.length; i++) {
+                    this.emit(elements[i]);
+                }
+            }
+        }
+        DeferredCollection.prototype.resolve = function resolve() {
+            this.promise.state = "resolved";
+            for (var i = 0; i < this.promise.resolveObservers.length; i++) {
+                this.promise.resolveObservers[i](this);
+            }
+        }
+        DeferredCollection.prototype.reject = function reject(e) {
+            this.promise.state = "rejected";
+            for (var i = 0; i < this.promise.rejectObservers.length; i++) {
+                this.promise.rejectObservers[i](e);
+            }
+            this.error = e;
+        }
+
+        /***********************************************
+         * Auxiliary Promised Collection Functionality *
+         ***********************************************/
+        
+        PromisedCollection.prototype.map = function map(f) {
+            var deferred = new DeferredCollection();
+            var promise = deferredCollection.promise;
+
+            this.forEach(function(element, index) {
+                deferred.emit(f(element, index));
+            });
+
+            this.then(function () {deferred.resolve();}, function(e) {deferred.reject(e);});
+            
+            return promise;
+        }
+
+        PromisedCollection.prototype.filter = function filter(f) {
+            var deferred = new DeferredCollection();
+            var promise = deferredCollection.promise;
+
+            this.forEach(function(element, index) {
+                if (f(element, index)) {
+                    deferred.emit(element);
+                }
+            });
+
+            this.then(function () {deferred.resolve();}, function(e) {deferred.reject(e);});
+            
+            return promise;
+        }
+
+        PromisedCollection.prototype.sort = function sort(f) {
+            var deferred = new DeferredCollection();
+            var promise = deferredCollection.promise;
+
+            var collection = this;
+            this.then(function (result) {
+                var data = result.deferred.data;
+                var copy = [];
+                for (var i = 0; i < data.length; i++) {
+                    copy.push(data[i]);
+                }
+                copy.sort(f);
+                for (var i = 0; i < copy.length; i++) {
+                    deferred.emit(copy[i]);
+                }
+                deferred.resolve();
+            }, function(e) {deferred.reject(e);});
+            
+            return promise;
+        }
+
+        return DeferredCollection;
+    })();
+}