Commit a79070b4 authored by Tristan Cavelier's avatar Tristan Cavelier

Add Promise progress

parent d6449937
......@@ -39,6 +39,11 @@ var Promise = function(resolver, canceller) {
reject(promise, value);
};
var notifyPromise = function(value) {
if (resolved) { return; }
notify(promise, value);
};
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
......@@ -62,7 +67,7 @@ var Promise = function(resolver, canceller) {
};
try {
resolver(resolvePromise, rejectPromise);
resolver(resolvePromise, rejectPromise, notifyPromise);
} catch(e) {
rejectPromise(e);
}
......@@ -104,6 +109,22 @@ var invokeCallback = function(type, promise, callback, event) {
}
};
var invokeNotifyCallback = function(promise, callback, event) {
var value;
if (typeof callback === 'function') {
try {
value = callback(event.detail);
} catch (e) {
// stop propagating
return;
}
notify(promise, value);
} else {
notify(promise, event.detail);
}
};
Promise.prototype = {
constructor: Promise,
......@@ -112,7 +133,7 @@ Promise.prototype = {
rejectedReason: undefined,
fulfillmentValue: undefined,
then: function(done, fail) {
then: function(done, fail, progress) {
this.off('error', onerror);
var thenPromise = new this.constructor(function() {},
......@@ -140,6 +161,10 @@ Promise.prototype = {
invokeCallback('reject', thenPromise, fail, event);
});
this.on('promise:notified', function (event) {
invokeNotifyCallback(thenPromise, progress, event);
});
return thenPromise;
},
......@@ -221,4 +246,10 @@ function reject(promise, value) {
});
}
function notify(promise, value) {
config.async(function() {
promise.trigger('promise:notified', { detail: value });
});
}
export { Promise };
......@@ -178,6 +178,64 @@ describe("RSVP extensions", function() {
});
it('notify should exist', function (done) {
var exists, promise = new RSVP.Promise(function (resolve, reject, notify) {
exists = typeof notify === 'function';
});
setTimeout(function () {
assert(exists);
done();
}, 20);
});
it('should notify if `notify` is called with a value', function (done) {
var promise = new RSVP.Promise(function (resolve, reject, notify) {
notify('foo');
});
promise.then(null, null, function (foo) {
assert.equal(foo, 'foo');
done();
});
});
it('should notify twice before resolve', function (done) {
var notified = 0, promise = new RSVP.Promise(function (resolve, reject, notify) {
notify('foo');
notify('bar');
resolve('end');
notify('should not be notified');
});
promise.then(function () {
var currently_notified = notified;
setTimeout(function () {
assert.equal(currently_notified, 2);
assert.equal(notified, 2);
done();
}, 50);
}, null, function () {
notified += 1;
});
});
it('notify should propagate on two then', function (done) {
var last_notified = false, promise = new RSVP.Promise(function (resolve, reject, notify) {
notify('foo');
});
promise.then(null, null, function (foo) {
assert.equal(foo, 'foo');
return 'bar';
}).then(null, null, function (bar) {
assert.equal(bar, 'bar');
setTimeout(function () {
assert(!last_notified);
done();
}, 50);
throw 'baz';
}).then(null, null, function () {
last_notified = true;
});
});
describe('assimilation', function() {
it('should assimilate if `resolve` is called with a fulfilled promise', function(done) {
var originalPromise = new RSVP.Promise(function(resolve) { resolve('original value'); });
......
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