Permalink
Browse files

.progress, .notify added (#23)

  • Loading branch information...
1 parent 114b554 commit 442fc0f3059bb3cece5542df1f88a501c7fbf956 @dfilatov committed Mar 28, 2013
Showing with 150 additions and 28 deletions.
  1. +1 −1 benchmarks/data.js
  2. +51 −25 lib/vow.js
  3. +59 −0 test/promise.notify.js
  4. +27 −1 test/promise.then.js
  5. +12 −1 test/vow.when.js
View
@@ -7,4 +7,4 @@ var res = {};
}
});
-module.exports = res;
+module.exports = res;
View
@@ -19,6 +19,7 @@ var Promise = function(val) {
this._fulfilledCallbacks = [];
this._rejectedCallbacks = [];
+ this._progressCallbacks = [];
};
Promise.prototype = {
@@ -46,8 +47,8 @@ Promise.prototype = {
this._isFulfilled = true;
this._res = val;
- this._callCallbacks(this._fulfilledCallbacks);
- this._fulfilledCallbacks = this._rejectedCallbacks = undef;
+ this._callCallbacks(this._fulfilledCallbacks, val);
+ this._fulfilledCallbacks = this._rejectedCallbacks = this._progressCallbacks = undef;
},
reject : function(err) {
@@ -58,28 +59,38 @@ Promise.prototype = {
this._isRejected = true;
this._res = err;
- this._callCallbacks(this._rejectedCallbacks);
- this._fulfilledCallbacks = this._rejectedCallbacks = undef;
+ this._callCallbacks(this._rejectedCallbacks, err);
+ this._fulfilledCallbacks = this._rejectedCallbacks = this._progressCallbacks = undef;
},
- then : function(onFulfilled, onRejected) {
+ notify : function(val) {
+ if(this.isResolved()) {
+ return;
+ }
+
+ this._callCallbacks(this._progressCallbacks, val);
+ },
+
+ then : function(onFulfilled, onRejected, onProgress) {
var promise = new Promise(),
cb;
if(!this._isRejected) {
cb = { promise : promise, fn : onFulfilled };
this._isFulfilled?
- this._callCallbacks([cb]) :
+ this._callCallbacks([cb], this._res) :
this._fulfilledCallbacks.push(cb);
}
if(!this._isFulfilled) {
cb = { promise : promise, fn : onRejected };
this._isRejected?
- this._callCallbacks([cb]) :
+ this._callCallbacks([cb], this._res) :
this._rejectedCallbacks.push(cb);
}
+ this.isResolved() || this._progressCallbacks.push({ promise : promise, fn : onProgress });
+
return promise;
},
@@ -96,6 +107,10 @@ Promise.prototype = {
return this.then(cb, cb);
},
+ progress : function(onProgress) {
+ return this.then(undef, undef, onProgress);
+ },
+
spread : function(onFulfilled, onRejected) {
return this.then(
function(val) {
@@ -147,13 +162,13 @@ Promise.prototype = {
});
},
- _callCallbacks : function(callbacks) {
+ _callCallbacks : function(callbacks, arg) {
var len = callbacks.length;
if(!len) {
return;
}
- var arg = this._res,
+ var isResolved = this.isResolved(),
isFulfilled = this.isFulfilled();
nextTick(function() {
@@ -173,22 +188,29 @@ Promise.prototype = {
continue;
}
- Vow.isPromise(res)?
- (function(promise) {
- res.then(
- function(val) {
- promise.fulfill(val);
- },
- function(err) {
- promise.reject(err);
- })
- })(promise) :
- promise.fulfill(res);
+ if(isResolved) {
+ Vow.isPromise(res)?
+ (function(promise) {
+ res.then(
+ function(val) {
+ promise.fulfill(val);
+ },
+ function(err) {
+ promise.reject(err);
+ })
+ })(promise) :
+ promise.fulfill(res);
+ }
+ else {
+ promise.notify(res);
+ }
}
else {
- isFulfilled?
- promise.fulfill(arg) :
- promise.reject(arg);
+ isResolved?
+ isFulfilled?
+ promise.fulfill(arg) :
+ promise.reject(arg) :
+ promise.notify(arg);
}
}
});
@@ -204,8 +226,8 @@ var Vow = {
new Promise();
},
- when : function(obj, onFulfilled, onRejected) {
- return this.promise(obj).then(onFulfilled, onRejected);
+ when : function(obj, onFulfilled, onRejected, onProgress) {
+ return this.promise(obj).then(onFulfilled, onRejected, onProgress);
},
fail : function(obj, onRejected) {
@@ -216,6 +238,10 @@ var Vow = {
return this.promise(obj).always(onResolved);
},
+ progress : function(obj, onProgress) {
+ return this.promise(obj).progress(onProgress);
+ },
+
spread : function(obj, onFulfilled, onRejected) {
return this.promise(obj).spread(onFulfilled, onRejected);
},
View
@@ -0,0 +1,59 @@
+module.exports = {
+ 'onProgress callbacks should be called on each notify' : function(test) {
+ var promise = Vow.promise(),
+ calledArgs1 = [],
+ calledArgs2 = [];
+
+ promise.progress(function(val) {
+ calledArgs1.push(val);
+ });
+
+ promise.then(null, null, function(val) {
+ calledArgs2.push(val);
+ });
+
+ promise.notify(1);
+ promise.notify(2);
+ promise.then(function() {
+ test.deepEqual(calledArgs1, [1, 2]);
+ test.deepEqual(calledArgs2, [1, 2]);
+ test.done();
+ });
+
+ promise.fulfill();
+ },
+
+ 'onProgress callbacks shouldn\'t be called after promise has been fulfilled' : function(test) {
+ var promise = Vow.promise(),
+ called = false;
+
+ promise.progress(function() {
+ called = true;
+ });
+
+ promise.fulfill();
+ promise.notify();
+ promise.notify();
+ promise.then(function() {
+ test.ok(!called);
+ test.done();
+ });
+ },
+
+ 'onProgress callbacks shouldn\'t be called after promise has been rejected' : function(test) {
+ var promise = Vow.promise(),
+ called = false;
+
+ promise.progress(function() {
+ called = true;
+ });
+
+ promise.reject();
+ promise.notify();
+ promise.notify();
+ promise.fail(function() {
+ test.ok(!called);
+ test.done();
+ });
+ }
+};
View
@@ -12,7 +12,7 @@ module.exports = {
'resulting promise should be rejected with same reason' : function(test) {
var promise = Vow.promise(),
- error = new Error('errot');
+ error = new Error('error');
promise.then().then(null, function(_error) {
test.strictEqual(_error, error);
@@ -22,6 +22,17 @@ module.exports = {
promise.reject(error);
},
+ 'resulting promise should be notified with same value' : function(test) {
+ var promise = Vow.promise();
+
+ promise.then().then(null, null, function(val) {
+ test.strictEqual(val, 1);
+ test.done();
+ });
+
+ promise.notify(1);
+ },
+
'resulting promise should be fulfilled with returned value of onFulfilled callback' : function(test) {
var promise = Vow.promise(),
resPromise = promise.then(function() {
@@ -101,5 +112,20 @@ module.exports = {
});
promise.reject();
+ },
+
+ 'resulting promise should be notified with returned value of onProgress callback' : function(test) {
+ var promise = Vow.promise();
+
+ promise
+ .then(null, null, function(val) {
+ return val + 1;
+ })
+ .then(null, null, function(val) {
+ test.strictEqual(val, 2);
+ test.done();
+ });
+
+ promise.notify(1);
}
};
View
@@ -1,5 +1,5 @@
module.exports = {
- 'onFullfilled callback should be called when argument fulfilled' : function(test) {
+ 'onFulfilled callback should be called when argument fulfilled' : function(test) {
var promise = Vow.promise();
Vow.when(promise, function(val) {
@@ -26,5 +26,16 @@ module.exports = {
test.strictEqual(val, 'val');
test.done();
});
+ },
+
+ 'onProgress callback should be called when argument notified' : function(test) {
+ var promise = Vow.promise();
+
+ Vow.when(promise, null, null, function(val) {
+ test.strictEqual(val, 'val');
+ test.done();
+ });
+
+ promise.notify('val');
}
};

0 comments on commit 442fc0f

Please sign in to comment.