Commit a6cb2f64 authored by Tomhuda Katzdale's avatar Tomhuda Katzdale

Make RSVP's API more aligned with general practice

parent 9d7fa43c
......@@ -144,7 +144,23 @@ define(
}
};
var Promise = function() {
var noop = function() {};
var Promise = function(resolver) {
var promise = this;
var resolvePromise = function(value) {
resolve(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
var rejectPromise = function(value) {
reject(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
......@@ -152,9 +168,11 @@ define(
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
};
var noop = function() {};
if (resolver) {
resolver(resolvePromise, rejectPromise);
}
};
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function',
......@@ -175,16 +193,18 @@ define(
if (value && typeof value.then === 'function') {
value.then(function(value) {
promise.resolve(value);
resolve(promise, value);
}, function(error) {
promise.reject(error);
reject(promise, error);
});
} else if (hasCallback && succeeded) {
promise.resolve(value);
resolve(promise, value);
} else if (failed) {
promise.reject(error);
} else {
promise[type](value);
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
......@@ -213,20 +233,6 @@ define(
});
return thenPromise;
},
resolve: function(value) {
resolve(this, value);
this.resolve = noop;
this.reject = noop;
},
reject: function(value) {
reject(this, value);
this.resolve = noop;
this.reject = noop;
}
};
......@@ -252,28 +258,28 @@ define(
var remaining = promises.length;
if (remaining === 0) {
allPromise.resolve([]);
resolve(allPromise, []);
}
var resolver = function(index) {
return function(value) {
resolve(index, value);
resolveAll(index, value);
};
};
var resolve = function(index, value) {
var resolveAll = function(index, value) {
results[index] = value;
if (--remaining === 0) {
allPromise.resolve(results);
resolve(allPromise, results);
}
};
var reject = function(error) {
allPromise.reject(error);
var rejectAll = function(error) {
reject(allPromise, error);
};
for (i = 0; i < remaining; i++) {
promises[i].then(resolver(i), reject);
promises[i].then(resolver(i), rejectAll);
}
return allPromise;
}
......
......@@ -142,7 +142,23 @@
}
};
var Promise = function() {
var noop = function() {};
var Promise = function(resolver) {
var promise = this;
var resolvePromise = function(value) {
resolve(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
var rejectPromise = function(value) {
reject(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
......@@ -150,9 +166,11 @@
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
};
var noop = function() {};
if (resolver) {
resolver(resolvePromise, rejectPromise);
}
};
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function',
......@@ -173,16 +191,18 @@
if (value && typeof value.then === 'function') {
value.then(function(value) {
promise.resolve(value);
resolve(promise, value);
}, function(error) {
promise.reject(error);
reject(promise, error);
});
} else if (hasCallback && succeeded) {
promise.resolve(value);
resolve(promise, value);
} else if (failed) {
promise.reject(error);
} else {
promise[type](value);
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
......@@ -211,20 +231,6 @@
});
return thenPromise;
},
resolve: function(value) {
resolve(this, value);
this.resolve = noop;
this.reject = noop;
},
reject: function(value) {
reject(this, value);
this.resolve = noop;
this.reject = noop;
}
};
......@@ -250,28 +256,28 @@
var remaining = promises.length;
if (remaining === 0) {
allPromise.resolve([]);
resolve(allPromise, []);
}
var resolver = function(index) {
return function(value) {
resolve(index, value);
resolveAll(index, value);
};
};
var resolve = function(index, value) {
var resolveAll = function(index, value) {
results[index] = value;
if (--remaining === 0) {
allPromise.resolve(results);
resolve(allPromise, results);
}
};
var reject = function(error) {
allPromise.reject(error);
var rejectAll = function(error) {
reject(allPromise, error);
};
for (i = 0; i < remaining; i++) {
promises[i].then(resolver(i), reject);
promises[i].then(resolver(i), rejectAll);
}
return allPromise;
}
......
(function(e){"use strict";function v(e,n){t.async(function(){e.trigger("promise:resolved",{detail:n}),e.isResolved=!0,e.resolvedValue=n})}function m(e,n){t.async(function(){e.trigger("promise:failed",{detail:n}),e.isRejected=!0,e.rejectedValue=n})}function g(e){var t,n=[],r=new h,i=e.length;i===0&&r.resolve([]);var s=function(e){return function(t){o(e,t)}},o=function(e,t){n[e]=t,--i===0&&r.resolve(n)},u=function(e){r.reject(e)};for(t=0;t<i;t++)e[t].then(s(t),u);return r}function y(e,n){t[e]=n}var t={},n=typeof window!="undefined"?window:{},r=n.MutationObserver||n.WebKitMutationObserver,i;if(typeof process!="undefined"&&{}.toString.call(process)==="[object process]")t.async=function(e,t){process.nextTick(function(){e.call(t)})};else if(r){var s=[],o=new r(function(){var e=s.slice();s=[],e.forEach(function(e){var t=e[0],n=e[1];t.call(n)})}),u=document.createElement("div");o.observe(u,{attributes:!0}),window.addEventListener("unload",function(){o.disconnect(),o=null}),t.async=function(e,t){s.push([e,t]),u.setAttribute("drainQueue","drainQueue")}}else t.async=function(e,t){setTimeout(function(){e.call(t)},1)};var a=function(e,t){this.type=e;for(var n in t){if(!t.hasOwnProperty(n))continue;this[n]=t[n]}},f=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n][0]===t)return n;return-1},l=function(e){var t=e._promiseCallbacks;return t||(t=e._promiseCallbacks={}),t},c={mixin:function(e){return e.on=this.on,e.off=this.off,e.trigger=this.trigger,e},on:function(e,t,n){var r=l(this),i,s;e=e.split(/\s+/),n=n||this;while(s=e.shift())i=r[s],i||(i=r[s]=[]),f(i,t)===-1&&i.push([t,n])},off:function(e,t){var n=l(this),r,i,s;e=e.split(/\s+/);while(i=e.shift()){if(!t){n[i]=[];continue}r=n[i],s=f(r,t),s!==-1&&r.splice(s,1)}},trigger:function(e,t){var n=l(this),r,i,s,o,u;if(r=n[e])for(var f=0;f<r.length;f++)i=r[f],s=i[0],o=i[1],typeof t!="object"&&(t={detail:t}),u=new a(e,t),s.call(o,u)}},h=function(){this.on("promise:resolved",function(e){this.trigger("success",{detail:e.detail})},this),this.on("promise:failed",function(e){this.trigger("error",{detail:e.detail})},this)},p=function(){},d=function(e,t,n,r){var i=typeof n=="function",s,o,u,a;if(i)try{s=n(r.detail),u=!0}catch(f){a=!0,o=f}else s=r.detail,u=!0;s&&typeof s.then=="function"?s.then(function(e){t.resolve(e)},function(e){t.reject(e)}):i&&u?t.resolve(s):a?t.reject(o):t[e](s)};h.prototype={then:function(e,n){var r=new h;return this.isResolved&&t.async(function(){d("resolve",r,e,{detail:this.resolvedValue})},this),this.isRejected&&t.async(function(){d("reject",r,n,{detail:this.rejectedValue})},this),this.on("promise:resolved",function(t){d("resolve",r,e,t)}),this.on("promise:failed",function(e){d("reject",r,n,e)}),r},resolve:function(e){v(this,e),this.resolve=p,this.reject=p},reject:function(e){m(this,e),this.resolve=p,this.reject=p}},c.mixin(h.prototype),e.Promise=h,e.Event=a,e.EventTarget=c,e.all=g,e.configure=y})(window.RSVP={});
(function(e){"use strict";function v(e,n){t.async(function(){e.trigger("promise:resolved",{detail:n}),e.isResolved=!0,e.resolvedValue=n})}function m(e,n){t.async(function(){e.trigger("promise:failed",{detail:n}),e.isRejected=!0,e.rejectedValue=n})}function g(e){var t,n=[],r=new p,i=e.length;i===0&&v(r,[]);var s=function(e){return function(t){o(e,t)}},o=function(e,t){n[e]=t,--i===0&&v(r,n)},u=function(e){m(r,e)};for(t=0;t<i;t++)e[t].then(s(t),u);return r}function y(e,n){t[e]=n}var t={},n=typeof window!="undefined"?window:{},r=n.MutationObserver||n.WebKitMutationObserver,i;if(typeof process!="undefined"&&{}.toString.call(process)==="[object process]")t.async=function(e,t){process.nextTick(function(){e.call(t)})};else if(r){var s=[],o=new r(function(){var e=s.slice();s=[],e.forEach(function(e){var t=e[0],n=e[1];t.call(n)})}),u=document.createElement("div");o.observe(u,{attributes:!0}),window.addEventListener("unload",function(){o.disconnect(),o=null}),t.async=function(e,t){s.push([e,t]),u.setAttribute("drainQueue","drainQueue")}}else t.async=function(e,t){setTimeout(function(){e.call(t)},1)};var a=function(e,t){this.type=e;for(var n in t){if(!t.hasOwnProperty(n))continue;this[n]=t[n]}},f=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n][0]===t)return n;return-1},l=function(e){var t=e._promiseCallbacks;return t||(t=e._promiseCallbacks={}),t},c={mixin:function(e){return e.on=this.on,e.off=this.off,e.trigger=this.trigger,e},on:function(e,t,n){var r=l(this),i,s;e=e.split(/\s+/),n=n||this;while(s=e.shift())i=r[s],i||(i=r[s]=[]),f(i,t)===-1&&i.push([t,n])},off:function(e,t){var n=l(this),r,i,s;e=e.split(/\s+/);while(i=e.shift()){if(!t){n[i]=[];continue}r=n[i],s=f(r,t),s!==-1&&r.splice(s,1)}},trigger:function(e,t){var n=l(this),r,i,s,o,u;if(r=n[e])for(var f=0;f<r.length;f++)i=r[f],s=i[0],o=i[1],typeof t!="object"&&(t={detail:t}),u=new a(e,t),s.call(o,u)}},h=function(){},p=function(e){var t=this,n=function(e){v(t,e),n=h,r=h},r=function(e){m(t,e),n=h,r=h};this.on("promise:resolved",function(e){this.trigger("success",{detail:e.detail})},this),this.on("promise:failed",function(e){this.trigger("error",{detail:e.detail})},this),e&&e(n,r)},d=function(e,t,n,r){var i=typeof n=="function",s,o,u,a;if(i)try{s=n(r.detail),u=!0}catch(f){a=!0,o=f}else s=r.detail,u=!0;s&&typeof s.then=="function"?s.then(function(e){v(t,e)},function(e){m(t,e)}):i&&u?v(t,s):a?m(t,o):e==="resolve"?v(t,s):e==="reject"&&m(t,s)};p.prototype={then:function(e,n){var r=new p;return this.isResolved&&t.async(function(){d("resolve",r,e,{detail:this.resolvedValue})},this),this.isRejected&&t.async(function(){d("reject",r,n,{detail:this.rejectedValue})},this),this.on("promise:resolved",function(t){d("resolve",r,e,t)}),this.on("promise:failed",function(e){d("reject",r,n,e)}),r}},c.mixin(p.prototype),e.Promise=p,e.Event=a,e.EventTarget=c,e.all=g,e.configure=y})(window.RSVP={});
......@@ -140,7 +140,23 @@ var EventTarget = {
}
};
var Promise = function() {
var noop = function() {};
var Promise = function(resolver) {
var promise = this;
var resolvePromise = function(value) {
resolve(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
var rejectPromise = function(value) {
reject(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
......@@ -148,9 +164,11 @@ var Promise = function() {
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
};
var noop = function() {};
if (resolver) {
resolver(resolvePromise, rejectPromise);
}
};
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function',
......@@ -171,16 +189,18 @@ var invokeCallback = function(type, promise, callback, event) {
if (value && typeof value.then === 'function') {
value.then(function(value) {
promise.resolve(value);
resolve(promise, value);
}, function(error) {
promise.reject(error);
reject(promise, error);
});
} else if (hasCallback && succeeded) {
promise.resolve(value);
resolve(promise, value);
} else if (failed) {
promise.reject(error);
} else {
promise[type](value);
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
......@@ -209,20 +229,6 @@ Promise.prototype = {
});
return thenPromise;
},
resolve: function(value) {
resolve(this, value);
this.resolve = noop;
this.reject = noop;
},
reject: function(value) {
reject(this, value);
this.resolve = noop;
this.reject = noop;
}
};
......@@ -248,28 +254,28 @@ function all(promises) {
var remaining = promises.length;
if (remaining === 0) {
allPromise.resolve([]);
resolve(allPromise, []);
}
var resolver = function(index) {
return function(value) {
resolve(index, value);
resolveAll(index, value);
};
};
var resolve = function(index, value) {
var resolveAll = function(index, value) {
results[index] = value;
if (--remaining === 0) {
allPromise.resolve(results);
resolve(allPromise, results);
}
};
var reject = function(error) {
allPromise.reject(error);
var rejectAll = function(error) {
reject(allPromise, error);
};
for (i = 0; i < remaining; i++) {
promises[i].then(resolver(i), reject);
promises[i].then(resolver(i), rejectAll);
}
return allPromise;
}
......
......@@ -141,7 +141,23 @@ var EventTarget = {
}
};
var Promise = function() {
var noop = function() {};
var Promise = function(resolver) {
var promise = this;
var resolvePromise = function(value) {
resolve(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
var rejectPromise = function(value) {
reject(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
......@@ -149,9 +165,11 @@ var Promise = function() {
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
};
var noop = function() {};
if (resolver) {
resolver(resolvePromise, rejectPromise);
}
};
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function',
......@@ -172,16 +190,18 @@ var invokeCallback = function(type, promise, callback, event) {
if (value && typeof value.then === 'function') {
value.then(function(value) {
promise.resolve(value);
resolve(promise, value);
}, function(error) {
promise.reject(error);
reject(promise, error);
});
} else if (hasCallback && succeeded) {
promise.resolve(value);
resolve(promise, value);
} else if (failed) {
promise.reject(error);
} else {
promise[type](value);
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
......@@ -210,20 +230,6 @@ Promise.prototype = {
});
return thenPromise;
},
resolve: function(value) {
resolve(this, value);
this.resolve = noop;
this.reject = noop;
},
reject: function(value) {
reject(this, value);
this.resolve = noop;
this.reject = noop;
}
};
......@@ -249,28 +255,28 @@ function all(promises) {
var remaining = promises.length;
if (remaining === 0) {
allPromise.resolve([]);
resolve(allPromise, []);
}
var resolver = function(index) {
return function(value) {
resolve(index, value);
resolveAll(index, value);
};
};
var resolve = function(index, value) {
var resolveAll = function(index, value) {
results[index] = value;
if (--remaining === 0) {
allPromise.resolve(results);
resolve(allPromise, results);
}
};
var reject = function(error) {
allPromise.reject(error);
var rejectAll = function(error) {
reject(allPromise, error);
};
for (i = 0; i < remaining; i++) {
promises[i].then(resolver(i), reject);
promises[i].then(resolver(i), rejectAll);
}
return allPromise;
}
......
......@@ -6,34 +6,54 @@ describe("RSVP extensions", function() {
});
specify('fulfilled only after all of the other promises are fulfilled', function(done) {
var first = new RSVP.Promise();
var second = new RSVP.Promise();
var firstResolved, secondResolved, firstResolver, secondResolver;
var first = new RSVP.Promise(function(resolve) {
firstResolver = resolve;
});
first.then(function() {
firstResolved = true;
});
var second = new RSVP.Promise(function(resolve) {
secondResolver = resolve;
});
second.then(function() {
secondResolved = true;
});
setTimeout(function() {
first.resolve(true);
firstResolver(true);
}, 0);
setTimeout(function() {
second.resolve(true);
secondResolver(true);
}, 0);
RSVP.all([first, second]).then(function() {
assert(first.isResolved);
assert(second.isResolved);
assert(firstResolved);
assert(secondResolved);
done();
});
});
specify('rejected as soon as a promise is rejected', function(done) {
var first = new RSVP.Promise();
var second = new RSVP.Promise();
var firstResolver, secondResolver;
var first = new RSVP.Promise(function(resolve, reject) {
firstResolver = { resolve: resolve, reject: reject };
});
var second = new RSVP.Promise(function(resolve, reject) {
secondResolver = { resolve: resolve, reject: reject };
});
setTimeout(function() {
first.reject({});
firstResolver.reject({});
}, 0);
setTimeout(function() {
second.resolve(true);
secondResolver.resolve(true);
}, 5000);
RSVP.all([first, second]).then(function() {
......@@ -46,13 +66,23 @@ describe("RSVP extensions", function() {
});
specify('passes the resolved values of each promise to the callback in the correct order', function(done) {
var first = new RSVP.Promise();
var second = new RSVP.Promise();
var third = new RSVP.Promise();
var firstResolver, secondResolver, thirdResolver;
var first = new RSVP.Promise(function(resolve, reject) {
firstResolver = { resolve: resolve, reject: reject };
});
var second = new RSVP.Promise(function(resolve, reject) {
secondResolver = { resolve: resolve, reject: reject };
});
var third = new RSVP.Promise(function(resolve, reject) {
thirdResolver = { resolve: resolve, reject: reject };
});
third.resolve(3);
first.resolve(1);
second.resolve(2);
thirdResolver.resolve(3);
firstResolver.resolve(1);
secondResolver.resolve(2);
RSVP.all([first, second, third]).then(function(results) {
assert(results.length === 3);
......
......@@ -141,7 +141,17 @@ var EventTarget = {
}
};
var Promise = function() {
var Promise = function(resolver) {
var promise = this;
function resolvePromise(value) {
resolve(promise, value);
}
function rejectPromise(value) {
reject(promise, value);
}
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
......@@ -149,6 +159,10 @@ var Promise = function() {
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
if (resolver) {
resolver(resolvePromise, rejectPromise);
}
};
var noop = function() {};
......
......@@ -15,29 +15,26 @@ if (typeof RSVP !== 'undefined') {
var adapter = {};
adapter.fulfilled = function(value) {
var promise = new Promise();
promise.resolve(value);
return promise;
return new Promise(function(resolve, reject) {
resolve(value);
});
};
adapter.rejected = function(error) {
var promise = new Promise();
promise.reject(error);
return promise;
return new Promise(function(resolve, reject) {
reject(error);
});
};
adapter.pending = function () {
var promise = new Promise();
return {
promise: promise,
fulfill: function(value) {
promise.resolve(value);
},
reject: function(error) {
promise.reject(error);
}
};
var pending = {};
pending.promise = new Promise(function(resolve, reject) {
pending.fulfill = resolve;
pending.reject = reject;
});
return pending;
};
module.exports = global.adapter = adapter;
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment