Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

.progress, .notify added (#23)

  • Loading branch information...
commit 442fc0f3059bb3cece5542df1f88a501c7fbf956 1 parent 114b554
Filatov Dmitry authored March 28, 2013
2  benchmarks/data.js
@@ -7,4 +7,4 @@ var res = {};
7 7
     }
8 8
 });
9 9
 
10  
-module.exports = res;
  10
+module.exports = res;
76  lib/vow.js
@@ -19,6 +19,7 @@ var Promise = function(val) {
19 19
 
20 20
     this._fulfilledCallbacks = [];
21 21
     this._rejectedCallbacks = [];
  22
+    this._progressCallbacks = [];
22 23
 };
23 24
 
24 25
 Promise.prototype = {
@@ -46,8 +47,8 @@ Promise.prototype = {
46 47
         this._isFulfilled = true;
47 48
         this._res = val;
48 49
 
49  
-        this._callCallbacks(this._fulfilledCallbacks);
50  
-        this._fulfilledCallbacks = this._rejectedCallbacks = undef;
  50
+        this._callCallbacks(this._fulfilledCallbacks, val);
  51
+        this._fulfilledCallbacks = this._rejectedCallbacks = this._progressCallbacks = undef;
51 52
     },
52 53
 
53 54
     reject : function(err) {
@@ -58,28 +59,38 @@ Promise.prototype = {
58 59
         this._isRejected = true;
59 60
         this._res = err;
60 61
 
61  
-        this._callCallbacks(this._rejectedCallbacks);
62  
-        this._fulfilledCallbacks = this._rejectedCallbacks = undef;
  62
+        this._callCallbacks(this._rejectedCallbacks, err);
  63
+        this._fulfilledCallbacks = this._rejectedCallbacks = this._progressCallbacks = undef;
63 64
     },
64 65
 
65  
-    then : function(onFulfilled, onRejected) {
  66
+    notify : function(val) {
  67
+        if(this.isResolved()) {
  68
+            return;
  69
+        }
  70
+
  71
+        this._callCallbacks(this._progressCallbacks, val);
  72
+    },
  73
+
  74
+    then : function(onFulfilled, onRejected, onProgress) {
66 75
         var promise = new Promise(),
67 76
             cb;
68 77
 
69 78
         if(!this._isRejected) {
70 79
             cb = { promise : promise, fn : onFulfilled };
71 80
             this._isFulfilled?
72  
-                this._callCallbacks([cb]) :
  81
+                this._callCallbacks([cb], this._res) :
73 82
                 this._fulfilledCallbacks.push(cb);
74 83
         }
75 84
 
76 85
         if(!this._isFulfilled) {
77 86
             cb = { promise : promise, fn : onRejected };
78 87
             this._isRejected?
79  
-                this._callCallbacks([cb]) :
  88
+                this._callCallbacks([cb], this._res) :
80 89
                 this._rejectedCallbacks.push(cb);
81 90
         }
82 91
 
  92
+        this.isResolved() || this._progressCallbacks.push({ promise : promise, fn : onProgress });
  93
+
83 94
         return promise;
84 95
     },
85 96
 
@@ -96,6 +107,10 @@ Promise.prototype = {
96 107
         return this.then(cb, cb);
97 108
     },
98 109
 
  110
+    progress : function(onProgress) {
  111
+        return this.then(undef, undef, onProgress);
  112
+    },
  113
+
99 114
     spread : function(onFulfilled, onRejected) {
100 115
         return this.then(
101 116
             function(val) {
@@ -147,13 +162,13 @@ Promise.prototype = {
147 162
             });
148 163
     },
149 164
 
150  
-    _callCallbacks : function(callbacks) {
  165
+    _callCallbacks : function(callbacks, arg) {
151 166
         var len = callbacks.length;
152 167
         if(!len) {
153 168
             return;
154 169
         }
155 170
 
156  
-        var arg = this._res,
  171
+        var isResolved = this.isResolved(),
157 172
             isFulfilled = this.isFulfilled();
158 173
 
159 174
         nextTick(function() {
@@ -173,22 +188,29 @@ Promise.prototype = {
173 188
                         continue;
174 189
                     }
175 190
 
176  
-                    Vow.isPromise(res)?
177  
-                        (function(promise) {
178  
-                            res.then(
179  
-                                function(val) {
180  
-                                    promise.fulfill(val);
181  
-                                },
182  
-                                function(err) {
183  
-                                    promise.reject(err);
184  
-                                })
185  
-                        })(promise) :
186  
-                        promise.fulfill(res);
  191
+                    if(isResolved) {
  192
+                        Vow.isPromise(res)?
  193
+                            (function(promise) {
  194
+                                res.then(
  195
+                                    function(val) {
  196
+                                        promise.fulfill(val);
  197
+                                    },
  198
+                                    function(err) {
  199
+                                        promise.reject(err);
  200
+                                    })
  201
+                            })(promise) :
  202
+                            promise.fulfill(res);
  203
+                    }
  204
+                    else {
  205
+                        promise.notify(res);
  206
+                    }
187 207
                 }
188 208
                 else {
189  
-                    isFulfilled?
190  
-                        promise.fulfill(arg) :
191  
-                        promise.reject(arg);
  209
+                    isResolved?
  210
+                        isFulfilled?
  211
+                            promise.fulfill(arg) :
  212
+                            promise.reject(arg) :
  213
+                        promise.notify(arg);
192 214
                 }
193 215
             }
194 216
         });
@@ -204,8 +226,8 @@ var Vow = {
204 226
             new Promise();
205 227
     },
206 228
 
207  
-    when : function(obj, onFulfilled, onRejected) {
208  
-        return this.promise(obj).then(onFulfilled, onRejected);
  229
+    when : function(obj, onFulfilled, onRejected, onProgress) {
  230
+        return this.promise(obj).then(onFulfilled, onRejected, onProgress);
209 231
     },
210 232
 
211 233
     fail : function(obj, onRejected) {
@@ -216,6 +238,10 @@ var Vow = {
216 238
         return this.promise(obj).always(onResolved);
217 239
     },
218 240
 
  241
+    progress : function(obj, onProgress) {
  242
+        return this.promise(obj).progress(onProgress);
  243
+    },
  244
+
219 245
     spread : function(obj, onFulfilled, onRejected) {
220 246
         return this.promise(obj).spread(onFulfilled, onRejected);
221 247
     },
59  test/promise.notify.js
... ...
@@ -0,0 +1,59 @@
  1
+module.exports = {
  2
+    'onProgress callbacks should be called on each notify' : function(test) {
  3
+        var promise = Vow.promise(),
  4
+            calledArgs1 = [],
  5
+            calledArgs2 = [];
  6
+
  7
+        promise.progress(function(val) {
  8
+            calledArgs1.push(val);
  9
+        });
  10
+
  11
+        promise.then(null, null, function(val) {
  12
+            calledArgs2.push(val);
  13
+        });
  14
+
  15
+        promise.notify(1);
  16
+        promise.notify(2);
  17
+        promise.then(function() {
  18
+            test.deepEqual(calledArgs1, [1, 2]);
  19
+            test.deepEqual(calledArgs2, [1, 2]);
  20
+            test.done();
  21
+        });
  22
+
  23
+        promise.fulfill();
  24
+    },
  25
+
  26
+    'onProgress callbacks shouldn\'t be called after promise has been fulfilled' : function(test) {
  27
+        var promise = Vow.promise(),
  28
+            called = false;
  29
+
  30
+        promise.progress(function() {
  31
+            called = true;
  32
+        });
  33
+
  34
+        promise.fulfill();
  35
+        promise.notify();
  36
+        promise.notify();
  37
+        promise.then(function() {
  38
+            test.ok(!called);
  39
+            test.done();
  40
+        });
  41
+    },
  42
+
  43
+    'onProgress callbacks shouldn\'t be called after promise has been rejected' : function(test) {
  44
+        var promise = Vow.promise(),
  45
+            called = false;
  46
+
  47
+        promise.progress(function() {
  48
+            called = true;
  49
+        });
  50
+
  51
+        promise.reject();
  52
+        promise.notify();
  53
+        promise.notify();
  54
+        promise.fail(function() {
  55
+            test.ok(!called);
  56
+            test.done();
  57
+        });
  58
+    }
  59
+};
28  test/promise.then.js
@@ -12,7 +12,7 @@ module.exports = {
12 12
 
13 13
     'resulting promise should be rejected with same reason' : function(test) {
14 14
         var promise = Vow.promise(),
15  
-            error = new Error('errot');
  15
+            error = new Error('error');
16 16
 
17 17
         promise.then().then(null, function(_error) {
18 18
             test.strictEqual(_error, error);
@@ -22,6 +22,17 @@ module.exports = {
22 22
         promise.reject(error);
23 23
     },
24 24
 
  25
+    'resulting promise should be notified with same value' : function(test) {
  26
+        var promise = Vow.promise();
  27
+
  28
+        promise.then().then(null, null, function(val) {
  29
+            test.strictEqual(val, 1);
  30
+            test.done();
  31
+        });
  32
+
  33
+        promise.notify(1);
  34
+    },
  35
+
25 36
     'resulting promise should be fulfilled with returned value of onFulfilled callback' : function(test) {
26 37
         var promise = Vow.promise(),
27 38
             resPromise = promise.then(function() {
@@ -101,5 +112,20 @@ module.exports = {
101 112
         });
102 113
 
103 114
         promise.reject();
  115
+    },
  116
+
  117
+    'resulting promise should be notified with returned value of onProgress callback' : function(test) {
  118
+        var promise = Vow.promise();
  119
+
  120
+        promise
  121
+            .then(null, null, function(val) {
  122
+                return val + 1;
  123
+            })
  124
+            .then(null, null, function(val) {
  125
+                test.strictEqual(val, 2);
  126
+                test.done();
  127
+            });
  128
+
  129
+        promise.notify(1);
104 130
     }
105 131
 };
13  test/vow.when.js
... ...
@@ -1,5 +1,5 @@
1 1
 module.exports = {
2  
-    'onFullfilled callback should be called when argument fulfilled' : function(test) {
  2
+    'onFulfilled callback should be called when argument fulfilled' : function(test) {
3 3
         var promise = Vow.promise();
4 4
 
5 5
         Vow.when(promise, function(val) {
@@ -26,5 +26,16 @@ module.exports = {
26 26
             test.strictEqual(val, 'val');
27 27
             test.done();
28 28
         });
  29
+    },
  30
+
  31
+    'onProgress callback should be called when argument notified' : function(test) {
  32
+        var promise = Vow.promise();
  33
+
  34
+        Vow.when(promise, null, null, function(val) {
  35
+            test.strictEqual(val, 'val');
  36
+            test.done();
  37
+        });
  38
+
  39
+        promise.notify('val');
29 40
     }
30 41
 };

0 notes on commit 442fc0f

Please sign in to comment.
Something went wrong with that request. Please try again.