lib/faye-browser.js in faye-1.0.0 vs lib/faye-browser.js in faye-1.0.1
- old
+ new
@@ -1,10 +1,10 @@
(function() {
'use strict';
var Faye = {
- VERSION: '1.0.0',
+ VERSION: '1.0.1',
BAYEUX_VERSION: '1.0',
ID_LENGTH: 160,
JSONP_CALLBACK: 'jsonpcallback',
CONNECTION_TYPES: ['long-polling', 'cross-origin-long-polling', 'callback-polling', 'websocket', 'eventsource', 'in-process'],
@@ -369,12 +369,12 @@
var PENDING = 0,
FULFILLED = 1,
REJECTED = 2;
-var FORWARD = function(x) { return x },
- BREAK = function(x) { throw x };
+var RETURN = function(x) { return x },
+ THROW = function(x) { throw x };
var Promise = function(task) {
this._state = PENDING;
this._callbacks = [];
this._errbacks = [];
@@ -385,52 +385,77 @@
task(function(value) { fulfill(self, value) },
function(reason) { reject(self, reason) });
};
Promise.prototype.then = function(callback, errback) {
- var self = this;
- return new Promise(function(fulfill, reject) {
- var next = {fulfill: fulfill, reject: reject};
+ var next = {}, self = this;
+
+ next.promise = new Promise(function(fulfill, reject) {
+ next.fulfill = fulfill;
+ next.reject = reject;
+
registerCallback(self, callback, next);
registerErrback(self, errback, next);
});
+ return next.promise;
};
var registerCallback = function(promise, callback, next) {
- if (typeof callback !== 'function') callback = FORWARD;
+ if (typeof callback !== 'function') callback = RETURN;
var handler = function(value) { invoke(callback, value, next) };
if (promise._state === PENDING) {
promise._callbacks.push(handler);
} else if (promise._state === FULFILLED) {
- defer(function() { handler(promise._value) });
+ handler(promise._value);
}
};
var registerErrback = function(promise, errback, next) {
- if (typeof errback !== 'function') errback = BREAK;
+ if (typeof errback !== 'function') errback = THROW;
var handler = function(reason) { invoke(errback, reason, next) };
if (promise._state === PENDING) {
promise._errbacks.push(handler);
} else if (promise._state === REJECTED) {
- defer(function() { handler(promise._reason) });
+ handler(promise._reason);
}
};
var invoke = function(fn, value, next) {
+ defer(function() { _invoke(fn, value, next) });
+};
+
+var _invoke = function(fn, value, next) {
+ var called = false, outcome, type, then;
+
try {
- var outcome = fn(value);
- if (outcome && typeof outcome.then === 'function') {
- outcome.then(next.fulfill, next.reject);
- } else {
- next.fulfill(outcome);
- }
+ outcome = fn(value);
+ type = typeof outcome;
+ then = outcome !== null && (type === 'function' || type === 'object') && outcome.then;
+
+ if (outcome === next.promise)
+ return next.reject(new TypeError('Recursive promise chain detected'));
+
+ if (typeof then !== 'function') return next.fulfill(outcome);
+
+ then.call(outcome, function(v) {
+ if (called) return;
+ called = true;
+ _invoke(RETURN, v, next);
+ }, function(r) {
+ if (called) return;
+ called = true;
+ next.reject(r);
+ });
+
} catch (error) {
+ if (called) return;
+ called = true;
next.reject(error);
}
};
-var fulfill = Promise.fulfill = function(promise, value) {
+var fulfill = Promise.fulfill = Promise.resolve = function(promise, value) {
if (promise._state !== PENDING) return;
promise._state = FULFILLED;
promise._value = value;
promise._errbacks = [];
@@ -450,21 +475,21 @@
while (eb = errbacks.shift()) eb(reason);
};
Promise.defer = defer;
-Promise.pending = function() {
+Promise.deferred = Promise.pending = function() {
var tuple = {};
tuple.promise = new Promise(function(fulfill, reject) {
- tuple.fulfill = fulfill;
+ tuple.fulfill = tuple.resolve = fulfill;
tuple.reject = reject;
});
return tuple;
};
-Promise.fulfilled = function(value) {
+Promise.fulfilled = Promise.resolved = function(value) {
return new Promise(function(fulfill, reject) { fulfill(value) });
};
Promise.rejected = function(reason) {
return new Promise(function(fulfill, reject) { reject(reason) });
@@ -776,10 +801,15 @@
this._timeouts = this._timeouts || {};
var timeout = this._timeouts[name];
if (!timeout) return;
clearTimeout(timeout);
delete this._timeouts[name];
+ },
+
+ removeAllTimeouts: function() {
+ this._timeouts = this._timeouts || {};
+ for (var name in this._timeouts) this.removeTimeout(name);
}
};
Faye.Logging = {
LOG_LEVELS: {
@@ -2123,13 +2153,15 @@
this.errback(function() { callback.call(context, false) });
this.connect();
},
request: function(envelopes) {
+ this._pending = this._pending || new Faye.Set();
+ for (var i = 0, n = envelopes.length; i < n; i++) this._pending.add(envelopes[i]);
+
this.callback(function(socket) {
if (!socket) return;
- for (var i = 0, n = envelopes.length; i < n; i++) this._pending.add(envelopes[i]);
var messages = Faye.map(envelopes, function(e) { return e.message });
socket.send(Faye.toJSON(messages));
}, this);
this.connect();
},
@@ -2147,10 +2179,9 @@
var self = this;
socket.onopen = function() {
if (socket.headers) self._storeCookies(socket.headers['set-cookie']);
self._socket = socket;
- self._pending = new Faye.Set();
self._state = self.CONNECTED;
self._everConnected = true;
self._ping();
self.setDeferredStatus('succeeded', socket);
};
\ No newline at end of file