Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge with v0.7

  • Loading branch information...
commit 0f3d0ab4e0dc40c74a71189e9a7fa55388ed39ff 2 parents a82a293 + 27fb87c
Mariusz Nowak authored
Showing with 801 additions and 725 deletions.
  1. +4 −17 .lint
  2. +2 −0  .testignore
  3. +0 −9 Makefile
  4. +118 −111 README.md
  5. +24 −22 {lib → }/_ext.js
  6. +48 −0 assimilate.js
  7. +8 −8 benchmark/concurrent.js
  8. +5 −5 benchmark/one-after-another.js
  9. +91 −82 {lib → }/deferred.js
  10. +11 −9 {lib → }/ext/_process-arguments.js
  11. +22 −31 {lib → }/ext/array/map.js
  12. +25 −25 {lib → }/ext/array/reduce.js
  13. +20 −21 {lib → }/ext/array/some.js
  14. +1 −1  {lib → }/ext/function/call-async.js
  15. +5 −3 {lib → }/ext/function/delay.js
  16. +17 −12 {lib → }/ext/function/gate.js
  17. +10 −15 {lib → }/ext/function/promisify-sync.js
  18. 0  {lib → }/ext/function/promisify.js
  19. +16 −15 {lib → }/ext/promise/_array.js
  20. 0  {lib → }/ext/promise/aside.js
  21. +20 −9 {lib → }/ext/promise/catch.js
  22. +9 −24 {lib → }/ext/promise/cb.js
  23. 0  {lib → }/ext/promise/finally.js
  24. +12 −16 {lib → }/ext/promise/get.js
  25. +25 −27 {lib → }/ext/promise/invoke-async.js
  26. +24 −26 {lib → }/ext/promise/invoke.js
  27. 0  {lib → }/ext/promise/map.js
  28. +19 −22 {lib → }/ext/promise/match.js
  29. 0  {lib → }/ext/promise/reduce.js
  30. 0  {lib → }/ext/promise/some.js
  31. 0  {lib → }/index.js
  32. 0  {lib → }/invoke-async.js
  33. 0  {lib → }/is-promise.js
  34. 0  {lib → }/monitor.js
  35. +6 −15 package.json
  36. 0  {lib → }/profiler.js
  37. +16 −16 test/_ext.js
  38. +52 −0 test/assimilate.js
  39. +26 −17 test/deferred.js
  40. +5 −5 test/ext/_process-arguments.js
  41. +18 −16 test/ext/array/map.js
  42. +44 −42 test/ext/array/reduce.js
  43. +2 −2 test/ext/array/some.js
  44. +6 −6 test/ext/function/call-async.js
  45. +1 −1  test/ext/function/delay.js
  46. +9 −9 test/ext/function/gate.js
  47. +4 −4 test/ext/function/promisify-sync.js
  48. +6 −6 test/ext/function/promisify.js
  49. +6 −6 test/ext/promise/_array.js
  50. +1 −1  test/ext/promise/aside.js
  51. +2 −2 test/ext/promise/catch.js
  52. +1 −1  test/ext/promise/cb.js
  53. +1 −1  test/ext/promise/finally.js
  54. +5 −5 test/ext/promise/get.js
  55. +9 −19 test/ext/promise/invoke-async.js
  56. +10 −10 test/ext/promise/invoke.js
  57. +2 −2 test/ext/promise/map.js
  58. +4 −4 test/ext/promise/match.js
  59. +2 −2 test/ext/promise/reduce.js
  60. +2 −2 test/ext/promise/some.js
  61. +15 −11 test/index.js
  62. +6 −6 test/invoke-async.js
  63. +1 −1  test/is-promise.js
  64. +1 −1  test/monitor.js
  65. +1 −1  test/profiler.js
  66. +1 −1  test/valid-promise.js
  67. 0  {lib → }/valid-promise.js
21 .lint
View
@@ -22,25 +22,12 @@ predef+ console, Buffer
./examples/test-with-mocha-and-should.js
predef+ describe, it
-./lib/ext/array/map.js
+./ext/array
+./ext/function
bitwise
-./lib/ext/array/reduce.js
-bitwise
-
-./lib/ext/array/some.js
-bitwise
-
-./lib/ext/function/promisify-sync.js
-bitwise
-
-./lib/ext/function/promisify.js
-bitwise
-
-./lib/monitor.js
-predef+ console
-
-./lib/profiler.js
+./monitor.js
+./profiler.js
predef+ console
./test/index.js
2  .testignore
View
@@ -0,0 +1,2 @@
+/benchmark
+/examples
9 Makefile
View
@@ -1,9 +0,0 @@
-SHELL = bash
-
-install:
- npm install
-
-test:
- npm test
-
-.PHONY: install test
229 README.md
View
@@ -28,41 +28,41 @@ var writeFile = fs.writeFile;
// Read all filenames in given path
readdir(__dirname, function (err, files) {
- var result, waiting;
- if (err) {
- // if we're unable to get file listing throw error
- throw err;
- }
-
- // Filter *.js files and generated lib.js
- files = files.filter(function (file) {
- return (file.slice(-3) === '.js') && (file !== 'lib.js');
- });
-
- // Read content of each file
- waiting = 0;
- result = [];
- files.forEach(function (file, index) {
- ++waiting;
- readFile(file, function (err, content) {
- if (err) {
- // We were not able to read file content, throw error
- throw err;
- }
- result[index] = content;
-
- if (!--waiting) {
- // Got content of all files
- // Concatenate into one string and write into lib.js
- writeFile(__dirname + '/lib.js', result.join("\n"), function (err) {
- if (err) {
- // We cannot write lib.js file, throw error
- throw err;
- }
- });
- }
- });
- });
+ var result, waiting;
+ if (err) {
+ // if we're unable to get file listing throw error
+ throw err;
+ }
+
+ // Filter *.js files and generated lib.js
+ files = files.filter(function (file) {
+ return (file.slice(-3) === '.js') && (file !== 'lib.js');
+ });
+
+ // Read content of each file
+ waiting = 0;
+ result = [];
+ files.forEach(function (file, index) {
+ ++waiting;
+ readFile(file, function (err, content) {
+ if (err) {
+ // We were not able to read file content, throw error
+ throw err;
+ }
+ result[index] = content;
+
+ if (!--waiting) {
+ // Got content of all files
+ // Concatenate into one string and write into lib.js
+ writeFile(__dirname + '/lib.js', result.join("\n"), function (err) {
+ if (err) {
+ // We cannot write lib.js file, throw error
+ throw err;
+ }
+ });
+ }
+ });
+ });
});
```
@@ -78,19 +78,19 @@ var readFile = promisify(fs.readFile, 1); // Restrict arity to 1 + callback
var writeFile = promisify(fs.writeFile);
writeFile(__dirname + '/lib.js',
- // Read all filenames in given path
- readdir(__dirname)
+ // Read all filenames in given path
+ readdir(__dirname)
- // Filter *.js files and generated lib.js
- .invoke('filter', function (file) {
- return (file.slice(-3) === '.js') && (file !== 'lib.js');
- })
+ // Filter *.js files and generated lib.js
+ .invoke('filter', function (file) {
+ return (file.slice(-3) === '.js') && (file !== 'lib.js');
+ })
- // Read content of all files
- .map(readFile)
+ // Read content of all files
+ .map(readFile)
- // Concatenate files content into one string
- .invoke('join', '\n')
+ // Concatenate files content into one string
+ .invoke('join', '\n')
).done(); // If there was any error on the way throw it
```
@@ -105,7 +105,7 @@ See [examples folder](examples) for a demonstration of promises usage in some ot
In your project path:
- $ npm install deferred
+ $ npm install deferred
#### Browser
@@ -146,19 +146,26 @@ Let's create `delay` function decorator:
var deferred = require('deferred');
var delay = function (fn, timeout) {
- return function () {
- var def = deferred(), self = this, args = arguments;
-
- setTimeout(function () {
- def.resolve(fn.apply(self, args));
- }, timeout);
-
- return def.promise;
- };
+ return function () {
+ var def = deferred(), self = this, args = arguments;
+
+ setTimeout(function () {
+ var value;
+ try {
+ value = fn.apply(self, args));
+ } catch (e) {
+ def.reject(e);
+ return;
+ }
+ def.resolve(value);
+ }, timeout);
+
+ return def.promise;
+ };
};
var delayedAdd = delay(function (a, b) {
- return a + b;
+ return a + b;
}, 100);
var resultPromise = delayedAdd(2, 3);
@@ -166,8 +173,8 @@ var resultPromise = delayedAdd(2, 3);
console.log(deferred.isPromise(resultPromise)); // true
resultPromise(function (value) {
- // Invoked after 100 milliseconds
- console.log(value); // 5
+ // Invoked after 100 milliseconds
+ console.log(value); // 5
});
```
@@ -197,9 +204,9 @@ Promises by nature can be chained. `promise` function returns another promise wh
```javascript
delayedAdd(2, 3)(function (result) {
- return result * result
+ return result * result
})(function (result) {
- console.log(result); // 25
+ console.log(result); // 25
});
```
@@ -213,7 +220,7 @@ Promises can be nested. If a promise resolves with another promise, it's not rea
var def = deferred();
def.resolve(delayedAdd(2, 3)); // Resolve promise with another promise
def.promise(function (result) {
- console.log(5); // 5;
+ console.log(5); // 5;
});
```
@@ -228,11 +235,11 @@ To handle error, pass dedicated callback as second argument to promise function:
```javascript
delayedAdd(2, 3)(function (result) {
- throw new Error('Error!')
+ throw new Error('Error!')
})(function () {
- // never called
+ // never called
}, function (e) {
- // handle error;
+ // handle error;
});
```
@@ -243,9 +250,9 @@ To expose the errors that are not handled, end promise chain with `.done()`, the
```javascript
delayedAdd(2, 3)
(function (result) {
- throw new Error('Error!')
+ throw new Error('Error!')
})(function (result) {
- // never executed
+ // never executed
})
.done(); // throws error!
```
@@ -258,11 +265,11 @@ Signature of `done` function is same as for `then` (or promise itself)
```javascript
promise(function (value) {
- // process
+ // process
}).done(function (result) {
- // process result
+ // process result
}, function (err) {
- // handle error
+ // handle error
});
```
@@ -276,7 +283,7 @@ You may create initially resolved promises.
var promise = deferred(1);
promise(function (result) {
- console.log(result); // 1;
+ console.log(result); // 1;
});
```
@@ -290,11 +297,11 @@ There is a known convention (coined by Node.js) for working with asynchronous ca
var fs = require('fs');
fs.readFile(__filename, 'utf-8', function (err, content) {
- if (err) {
- // handle error;
- return;
- }
- // process content
+ if (err) {
+ // handle error;
+ return;
+ }
+ // process content
});
```
@@ -302,14 +309,14 @@ It's not convenient to work with both promises and callback style functions. Whe
```javascript
var deferred = require('deferred')
- , fs = require('fs')
+ , fs = require('fs')
- , readFile = deferred.promisify(fs.readFile);
+ , readFile = deferred.promisify(fs.readFile);
readFile(__filename, 'utf-8')(function (content) {
- // process content
+ // process content
}, function (err) {
- // handle error
+ // handle error
});
```
@@ -351,7 +358,7 @@ When we're interested in results of more than one promise object we may group th
```javascript
deferred(delayedAdd(2, 3), delayedAdd(3, 5), delayedAdd(1, 7))(function (result) {
- console.log(result); // [5, 8, 8]
+ console.log(result); // [5, 8, 8]
});
```
@@ -367,9 +374,9 @@ In following example we take content of each file found in an array:
var readFile = deferred.promisify(fs.readFile);
deferred.map(filenames, function (filename) {
- return readFile(filename, 'utf-8');
+ return readFile(filename, 'utf-8');
})(function (result) {
- // result is an array of file's contents
+ // result is an array of file's contents
});
```
@@ -382,9 +389,9 @@ var readdir = deferred.promisify(fs.readdir);
var readFile = deferred.promisify(fs.readFile);
readdir(__dirname).map(function (filename) {
- return readFile(filename, 'utf-8');
+ return readFile(filename, 'utf-8');
})(function (result) {
- // result is an array of file's contents
+ // result is an array of file's contents
});
```
@@ -398,10 +405,10 @@ It's same as Array's reduce with that difference that it calls callback only aft
```javascript
deferred.reduce([delayedAdd(2, 3), delayedAdd(3, 5), delayedAdd(1, 7)], function (a, b) {
- return delayedAdd(a, b);
+ return delayedAdd(a, b);
})
(function (result) {
- console.log(result); // 21
+ console.log(result); // 21
});
```
@@ -413,12 +420,12 @@ Promise aware Array's some. Process collection one after another and stop when f
```javascript
deferred.some([filename1, filename2, filename3], function (a) {
- return readFile(filename, 'utf8', function (data) {
- if (data.indexOf('needle')) {
- // Got it! Stop further processing
- return true;
- }
- });
+ return readFile(filename, 'utf8', function (data) {
+ if (data.indexOf('needle')) {
+ // Got it! Stop further processing
+ return true;
+ }
+ });
});
```
@@ -432,9 +439,9 @@ Handle that with `deferred.gate`, it wraps functions that return promises. It do
```javascript
var fn = deferred.gate(function async() {
- var def = deferred();
- // ..
- return def.promise;
+ var def = deferred();
+ // ..
+ return def.promise;
}, 10);
```
@@ -451,9 +458,9 @@ In following example we'll limit concurrent readFile calls when using deferred.m
```javascript
// Open maximum 100 file descriptors at once
deferred.map(filenames, deferred.gate(function (filename) {
- return readFile(filename, 'utf-8');
+ return readFile(filename, 'utf-8');
}, 100))(function (result) {
- // result is an array of file's contents
+ // result is an array of file's contents
});
```
@@ -496,10 +503,10 @@ Imagine recursive directory reader that scans whole file system and provides fil
```javascript
var reader = readdirDeep(rootPath); // reader promise is returned
reader.on('data', function (someFilenames) {
- // Called many times during scan with obtained names
+ // Called many times during scan with obtained names
});
reader.done(function (allFilenames) {
- // File-system scan finished!
+ // File-system scan finished!
});
```
@@ -517,7 +524,7 @@ var x = deferred({ foo: 'bar' });
var promise = deferred({ foo: 'bar' });
var y = promise.aside(function (value) {
- console.log(value === x); // true
+ console.log(value === x); // true
});
console.log(y === promise); // true
```
@@ -549,7 +556,7 @@ With cb we may build hybrid functions that do both, handle asynchronous callback
```javascript
var asyncFunction = function (x, y, callback) {
- return someAsyncProcessingThatReturnsPromise(x, y).cb(callback);
+ return someAsyncProcessingThatReturnsPromise(x, y).cb(callback);
});
```
@@ -575,11 +582,11 @@ To directly get to object property use `get`
var promise = deferred({ foo: 'bar' });
promise(function (obj) {
- console.log(obj.foo); // 'bar';
+ console.log(obj.foo); // 'bar';
})
promise.get('foo')(function (value) {
- console.log(value); // 'bar'
+ console.log(value); // 'bar'
});
```
@@ -589,11 +596,11 @@ You can get to nested properties as well:
var promise = deferred({ foo: { bar: 317 });
promise(function (obj) {
- console.log(obj.foo.bar); // 317;
+ console.log(obj.foo.bar); // 317;
})
promise.get('foo', 'bar')(function (value) {
- console.log(value); // 317
+ console.log(value); // 317
});
```
@@ -605,18 +612,18 @@ Schedule function call on returned object
var promise = deferred({ foo: function (arg) { return arg*arg; } });
promise.invoke('foo', 3)(function (result) {
- console.log(result); // 9
+ console.log(result); // 9
});
// For asynchronous functions use invokeAsync
var promise = deferred({ foo: function (arg, callback) {
- setTimeout(function () {
- callback(null, arg*arg);
- }, 100);
+ setTimeout(function () {
+ callback(null, arg*arg);
+ }, 100);
} });
promise.invokeAsync('foo', 3)(function (result) {
- console.log(result); // 9
+ console.log(result); // 9
});
```
@@ -632,7 +639,7 @@ If promise expected value is a list that you want to match into function argumen
var promise = deferred([2, 3]);
promise.match(function (a, b) {
- console.log(a + b); // 5
+ console.log(a + b); // 5
});
```
46 lib/_ext.js → _ext.js
View
@@ -6,8 +6,8 @@ var callable = require('es5-ext/object/valid-callable')
, ee = require('event-emitter/lib/core')
, isPromise = require('./is-promise')
- , create = Object.create, defineProperty = Object.defineProperty, deferred
- , doneFn;
+ , create = Object.create, defineProperty = Object.defineProperty
+ , deferred, resolve, reject;
module.exports = exports = function (name, unres, onres, res) {
name = String(name);
@@ -18,51 +18,55 @@ module.exports = exports = function (name, unres, onres, res) {
exports._names.push(name);
};
-exports._names = ['end', 'then', 'valueOf'];
+exports._names = ['done', 'then', 'valueOf'];
exports._unresolved = ee(create(Function.prototype, {
then: d(function (win, fail) {
var def;
if (!this.pending) this.pending = [];
def = deferred();
- this.pending.push('then', [win, fail, def.resolve]);
+ this.pending.push('then', [win, fail, def.resolve, def.reject]);
return def.promise;
}),
- done: d(doneFn = function (win, fail) {
+ done: d(function (win, fail) {
((win == null) || callable(win));
((fail == null) || callable(fail));
if (!this.pending) this.pending = [];
this.pending.push('done', arguments);
}),
- end: d(doneFn),
resolved: d(false),
returnsPromise: d(true),
valueOf: d(function () { return this; })
}));
exports._onresolve = {
- then: function (win, fail, resolve) {
+ then: function (win, fail, resolve, reject) {
var value, cb = this.failed ? fail : win;
if (cb == null) {
- resolve(this.value);
+ if (this.failed) reject(this.value);
+ else resolve(this.value);
return;
}
if (isCallable(cb)) {
if (isPromise(cb)) {
if (cb.resolved) {
- resolve(cb.value);
+ if (cb.failed) reject(cb.value);
+ else resolve(cb.value);
return;
}
- cb.end(resolve, resolve);
+ cb.done(resolve, reject);
+ return;
+ }
+ try { value = cb(this.value); } catch (e) {
+ reject(e);
return;
}
- try { value = cb(this.value); } catch (e) { value = e; }
resolve(value);
return;
}
resolve(cb);
},
- done: doneFn = function (win, fail) {
+ done: function (win, fail) {
if (this.failed) {
if (fail) {
fail(this.value);
@@ -71,24 +75,21 @@ exports._onresolve = {
throw this.value;
}
if (win) win(this.value);
- },
- end: doneFn
+ }
};
exports._resolved = ee(create(Function.prototype, {
then: d(function (win, fail) {
var value, cb = this.failed ? fail : win;
- if (cb == null) {
- return this;
- }
+ if (cb == null) return this;
if (isCallable(cb)) {
if (isPromise(cb)) return cb;
- try { value = cb(this.value); } catch (e) { value = e; }
- return deferred(value);
+ try { value = cb(this.value); } catch (e) { return reject(e); }
+ return resolve(value);
}
- return deferred(cb);
+ return resolve(cb);
}),
- done: d(doneFn = function (win, fail) {
+ done: d(function (win, fail) {
((win == null) || callable(win));
((fail == null) || callable(fail));
if (this.failed) {
@@ -100,11 +101,12 @@ exports._resolved = ee(create(Function.prototype, {
}
if (win) win(this.value);
}),
- end: d(doneFn),
resolved: d(true),
returnsPromise: d(true),
valueOf: d(function () { return this.value; })
}));
deferred = require('./deferred');
+resolve = deferred.resolve;
+reject = deferred.reject;
deferred.extend = exports;
48 assimilate.js
View
@@ -0,0 +1,48 @@
+// Assimilate eventual foreign promise
+
+'use strict';
+
+var isObject = require('es5-ext/object/is-object')
+ , isPromise = require('./is-promise')
+ , deferred = require('./deferred')
+ , nextTick = require('next-tick')
+
+ , getPrototypeOf = Object.getPrototypeOf;
+
+module.exports = function self(value) {
+ var then, done, def, resolve, reject;
+ if (!value) return value;
+ try {
+ then = value.then;
+ } catch (e) {
+ return value;
+ }
+ if (typeof then !== 'function') return value;
+ if (isPromise(value)) return value;
+ if (!isObject(value)) return value;
+ if (!getPrototypeOf(value)) return value;
+ try {
+ done = value.done;
+ } catch (ignore) {}
+ def = deferred();
+ resolve = function (value) { def.resolve(self(value)); };
+ reject = function (value) { def.reject(value); };
+ if (typeof done === 'function') {
+ try {
+ done.call(value, resolve, reject);
+ } catch (e) {
+ return def.reject(e);
+ }
+ return def.promise;
+ }
+ try {
+ then.call(value, function (value) { nextTick(function () {
+ resolve(value);
+ }); }, function (value) { nextTick(function () {
+ reject(value);
+ }); });
+ } catch (e) {
+ return def.reject(e);
+ }
+ return def.promise;
+};
16 benchmark/concurrent.js
View
@@ -14,7 +14,7 @@ var generate = require('es5-ext/array/generate')
, Bluebird = require('bluebird')
, kew = require('kew')
, when = require('when')
- , deferred = require('../lib')
+ , deferred = require('../')
, now = Date.now
, Deferred = deferred.Deferred
@@ -171,7 +171,7 @@ tests = [function () {
};
self = function () {
- dlstat(__filename).end(function () {
+ dlstat(__filename).done(function () {
if (!--i) next(); // Ignore first
});
};
@@ -186,7 +186,7 @@ tests = [function () {
};
self = function () {
- dlstat(__filename).end(function () {
+ dlstat(__filename).done(function () {
if (!--i) {
data["Deferred: Dedicated wrapper"] = now() - time;
next();
@@ -199,7 +199,7 @@ tests = [function () {
var i = count, j = count, dlstat = promisify(lstat);
self = function () {
- dlstat(__filename).end(function () {
+ dlstat(__filename).done(function () {
if (!--i) next(); // Ignore first
});
};
@@ -209,7 +209,7 @@ tests = [function () {
var i = count, j = count, dlstat = promisify(lstat);
self = function () {
- dlstat(__filename).end(function () {
+ dlstat(__filename).done(function () {
if (!--i) {
data["Deferred: Promisify (generic wrapper)"] = now() - time;
next();
@@ -224,7 +224,7 @@ tests = [function () {
time = now();
deferred.map(files, function (name) {
return dlstat(name);
- }).end(function () {
+ }).done(function () {
next();
});
}, function () {
@@ -233,14 +233,14 @@ tests = [function () {
time = now();
deferred.map(files, function (name) {
return dlstat(name);
- }).end(function () { next(); });
+ }).done(function () { next(); });
}, function () {
var dlstat = promisify(lstat);
time = now();
deferred.map(files, function (name) {
return dlstat(name);
- }).end(function () {
+ }).done(function () {
data["Deferred: Map + Promisify"] = now() - time;
next();
});
10 benchmark/one-after-another.js
View
@@ -14,7 +14,7 @@ var forEach = require('es5-ext/object/for-each')
, Bluebird = require('bluebird')
, kew = require('kew')
, when = require('when')
- , deferred = require('../lib')
+ , deferred = require('../')
, now = Date.now
, Deferred = deferred.Deferred, promisify = deferred.promisify
@@ -185,7 +185,7 @@ tests = [function () {
};
self = function () {
- dlstat(__filename).end(function (stats) {
+ dlstat(__filename).done(function (stats) {
if (--i) self(stats);
else next(); // Ignore first one
});
@@ -202,7 +202,7 @@ tests = [function () {
};
self = function () {
- dlstat(__filename).end(function (stats) {
+ dlstat(__filename).done(function (stats) {
if (--i) {
self(stats);
} else {
@@ -217,7 +217,7 @@ tests = [function () {
var i = count, dlstat = promisify(lstat);
self = function () {
- dlstat(__filename).end(function (stats) {
+ dlstat(__filename).done(function (stats) {
if (--i) self(stats);
else next(); // Ignore first one
});
@@ -228,7 +228,7 @@ tests = [function () {
var i = count, dlstat = promisify(lstat);
self = function () {
- dlstat(__filename).end(function (stats) {
+ dlstat(__filename).done(function (stats) {
if (--i) {
self(stats);
} else {
173 lib/deferred.js → deferred.js
View
@@ -12,14 +12,14 @@
'use strict';
var isError = require('es5-ext/error/is-error')
- , validError = require('es5-ext/error/valid-error')
, noop = require('es5-ext/function/noop')
, isPromise = require('./is-promise')
, every = Array.prototype.every, push = Array.prototype.push
, Deferred, createDeferred, count = 0, timeout, extendShim, ext
- , protoSupported = Boolean(isPromise.__proto__);
+ , protoSupported = Boolean(isPromise.__proto__)
+ , resolve, assimilate;
extendShim = function (promise) {
ext._names.forEach(function (name) {
@@ -31,17 +31,23 @@ extendShim = function (promise) {
promise.resolved = promise.__proto__.resolved;
};
+resolve = function (value, failed) {
+ var promise = function (win, fail) { return promise.then(win, fail); };
+ promise.value = value;
+ promise.failed = failed;
+ promise.__proto__ = ext._resolved;
+ if (!protoSupported) { extendShim(promise); }
+ if (createDeferred._profile) createDeferred._profile(true);
+ return promise;
+};
+
Deferred = function () {
var promise = function (win, fail) { return promise.then(win, fail); };
- if (!count) {
- timeout = setTimeout(noop, 1e9);
- }
+ if (!count) timeout = setTimeout(noop, 1e9);
++count;
- if (createDeferred._monitor) {
- promise.monitor = createDeferred._monitor();
- }
+ if (createDeferred._monitor) promise.monitor = createDeferred._monitor();
promise.__proto__ = ext._unresolved;
- if (!protoSupported) { extendShim(promise); }
+ if (!protoSupported) extendShim(promise);
(createDeferred._profile && createDeferred._profile());
this.promise = promise;
this.resolve = this.resolve.bind(this);
@@ -50,18 +56,39 @@ Deferred = function () {
Deferred.prototype = {
resolved: false,
- resolve: function (value) {
+ _settle: function (value) {
var i, name, data;
- if (this.resolved) {
- return this.promise;
- }
- this.resolved = true;
- if (!--count) {
- clearTimeout(timeout);
+ this.promise.value = value;
+ this.promise.__proto__ = ext._resolved;
+ if (!protoSupported) this.promise.resolved = true;
+ if (this.promise.dependencies) {
+ this.promise.dependencies.forEach(function self(dPromise) {
+ dPromise.value = value;
+ dPromise.failed = this.failed;
+ dPromise.__proto__ = ext._resolved;
+ if (!protoSupported) dPromise.resolved = true;
+ delete dPromise.pending;
+ if (dPromise.dependencies) {
+ dPromise.dependencies.forEach(self, this);
+ delete dPromise.dependencies;
+ }
+ }, this.promise);
+ delete this.promise.dependencies;
}
- if (this.promise.monitor) {
- clearTimeout(this.promise.monitor);
+ if ((data = this.promise.pending)) {
+ for (i = 0; (name = data[i]); ++i) {
+ ext._onresolve[name].apply(this.promise, data[++i]);
+ }
+ delete this.promise.pending;
}
+ return this.promise;
+ },
+ resolve: function (value) {
+ if (this.resolved) return this.promise;
+ this.resolved = true;
+ if (!--count) clearTimeout(timeout);
+ if (this.promise.monitor) clearTimeout(this.promise.monitor);
+ value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
if (!value.dependencies) {
@@ -90,82 +117,64 @@ Deferred.prototype = {
}
return this.promise;
}
+ this.promise.failed = value.failed;
value = value.value;
}
- this.promise.value = value;
- this.promise.failed = (value && isError(value)) || false;
- this.promise.__proto__ = ext._resolved;
- if (!protoSupported) {
- this.promise.resolved = true;
- }
- if (this.promise.dependencies) {
- this.promise.dependencies.forEach(function self(dPromise) {
- dPromise.value = value;
- dPromise.failed = this.failed;
- dPromise.__proto__ = ext._resolved;
- if (!protoSupported) {
- dPromise.resolved = true;
- }
- delete dPromise.pending;
- if (dPromise.dependencies) {
- dPromise.dependencies.forEach(self, this);
- delete dPromise.dependencies;
- }
- }, this.promise);
- delete this.promise.dependencies;
- }
- if ((data = this.promise.pending)) {
- for (i = 0; (name = data[i]); ++i) {
- ext._onresolve[name].apply(this.promise, data[++i]);
- }
- delete this.promise.pending;
- }
- return this.promise;
+ return this._settle(value);
},
- reject: function (error) { return this.resolve(validError(error)); }
+ reject: function (error) {
+ if (this.resolved) return this.promise;
+ this.resolved = true;
+ if (!--count) clearTimeout(timeout);
+ if (this.promise.monitor) clearTimeout(this.promise.monitor);
+ this.promise.failed = true;
+ return this._settle(error);
+ }
};
module.exports = createDeferred = function (value) {
- var l, d, waiting, initialized, result, promise;
- if ((l = arguments.length)) {
- if (l > 1) {
- d = new Deferred();
- waiting = 0;
- result = new Array(l);
- every.call(arguments, function (value, index) {
- if (isPromise(value)) {
- ++waiting;
- value.end(function (value) {
- result[index] = value;
- if (!--waiting && initialized) {
- d.resolve(result);
- }
- }, d.resolve);
- } else if (!isError(value)) {
- result[index] = value;
- } else {
- d.resolve(value);
+ var l = arguments.length, d, waiting, initialized, result;
+ if (!l) return new Deferred();
+ if (l > 1) {
+ d = new Deferred();
+ waiting = 0;
+ result = new Array(l);
+ every.call(arguments, function (value, index) {
+ value = assimilate(value);
+ if (!isPromise(value)) {
+ result[index] = value;
+ return true;
+ }
+ if (value.resolved) {
+ if (value.failed) {
+ d.reject(value.value);
return false;
}
+ result[index] = value.value;
return true;
- });
- initialized = true;
- if (!waiting) {
- d.resolve(result);
}
- return d.promise;
- }
- if (isPromise(value)) return value;
- promise = function (win, fail) { return promise.then(win, fail); };
- promise.value = value;
- promise.failed = isError(value);
- promise.__proto__ = ext._resolved;
- if (!protoSupported) { extendShim(promise); }
- if (createDeferred._profile) createDeferred._profile(true);
- return promise;
+ ++waiting;
+ value.done(function (value) {
+ result[index] = value;
+ if (!--waiting && initialized) d.resolve(result);
+ }, d.reject);
+ return true;
+ });
+ initialized = true;
+ if (!waiting) d.resolve(result);
+ return d.promise;
}
- return new Deferred();
+ value = assimilate(value);
+ if (isPromise(value)) return value;
+ return resolve(value, isError(value));
};
createDeferred.Deferred = Deferred;
+createDeferred.reject = function (value) { return resolve(value, true); };
+createDeferred.resolve = function (value) {
+ value = assimilate(value);
+ if (isPromise(value)) return value;
+ return resolve(value, false);
+};
ext = require('./_ext');
+assimilate = require('./assimilate');
20 lib/ext/_process-arguments.js → ext/_process-arguments.js
View
@@ -1,13 +1,14 @@
'use strict';
-var arrayOf = require('es5-ext/array/of')
- , deferred = require('../deferred')
- , isPromise = require('../is-promise')
+var arrayOf = require('es5-ext/array/of')
+ , deferred = require('../deferred')
+ , isPromise = require('../is-promise')
+ , assimilate = require('../assimilate')
, push = Array.prototype.push, slice = Array.prototype.slice;
module.exports = function (args, length) {
- var i, l;
+ var i, l, arg;
if ((length != null) && (args.length !== length)) {
args = slice.call(args, 0, length);
if (args.length < length) {
@@ -15,13 +16,14 @@ module.exports = function (args, length) {
}
}
for (i = 0, l = args.length; i < l; ++i) {
- if (isPromise(args[i])) {
- if (!args[i].resolved) {
+ arg = assimilate(args[i]);
+ if (isPromise(arg)) {
+ if (!arg.resolved) {
if (l > 1) return deferred.apply(null, args);
- return args[0](arrayOf);
+ return arg(arrayOf);
}
- if (args[i].failed) return args[i];
- args[i] = args[i].value;
+ if (arg.failed) return arg;
+ args[i] = arg.value;
}
}
return args;
53 lib/ext/array/map.js → ext/array/map.js
View
@@ -2,12 +2,12 @@
'use strict';
-var isError = require('es5-ext/error/is-error')
- , assign = require('es5-ext/object/assign')
- , value = require('es5-ext/object/valid-value')
- , callable = require('es5-ext/object/valid-callable')
- , deferred = require('../../deferred')
- , isPromise = require('../../is-promise')
+var assign = require('es5-ext/object/assign')
+ , value = require('es5-ext/object/valid-value')
+ , callable = require('es5-ext/object/valid-callable')
+ , deferred = require('../../deferred')
+ , isPromise = require('../../is-promise')
+ , assimilate = require('../../assimilate')
, every = Array.prototype.every
, call = Function.prototype.call
@@ -22,9 +22,7 @@ DMap = function (list, cb, context) {
assign(this, deferred());
every.call(list, this.process, this);
- if (!this.waiting) {
- return this.resolve(this.result);
- }
+ if (!this.waiting) return this.resolve(this.result);
this.initialized = true;
return this.promise;
@@ -35,56 +33,49 @@ DMap.prototype = {
initialized: false,
process: function (value, index) {
++this.waiting;
+ value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
- value.end(this.processCb.bind(this, index), this.resolve);
+ value.done(this.processCb.bind(this, index), this.reject);
return true;
}
- value = value.value;
- if (isError(value)) {
- this.resolve(value);
+ if (value.failed) {
+ this.reject(value.value);
return false;
}
- } else if (isError(value) && !this.cb) {
- this.resolve(value);
- return false;
+ value = value.value;
}
return this.processCb(index, value);
},
processCb: function (index, value) {
- if (this.promise.resolved) {
- return false;
- }
+ if (this.promise.resolved) return false;
if (this.cb) {
try {
value = call.call(this.cb, this.context, value, index, this.list);
} catch (e) {
- this.resolve(e);
+ this.reject(e);
return false;
}
+ value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
- value.end(this.processValue.bind(this, index), this.resolve);
+ value.done(this.processValue.bind(this, index), this.reject);
return true;
}
+ if (value.failed) {
+ this.reject(value);
+ return false;
+ }
value = value.value;
}
- if (isError(value)) {
- this.resolve(value);
- return false;
- }
}
this.processValue(index, value);
return true;
},
processValue: function (index, value) {
- if (this.promise.resolved) {
- return;
- }
+ if (this.promise.resolved) return;
this.result[index] = value;
- if (!--this.waiting && this.initialized) {
- this.resolve(this.result);
- }
+ if (!--this.waiting && this.initialized) this.resolve(this.result);
}
};
50 lib/ext/array/reduce.js → ext/array/reduce.js
View
@@ -2,15 +2,16 @@
'use strict';
-var isError = require('es5-ext/error/is-error')
- , assign = require('es5-ext/object/assign')
- , value = require('es5-ext/object/valid-value')
- , callable = require('es5-ext/object/valid-callable')
- , deferred = require('../../deferred')
- , isPromise = require('../../is-promise')
+var assign = require('es5-ext/object/assign')
+ , value = require('es5-ext/object/valid-value')
+ , callable = require('es5-ext/object/valid-callable')
+ , deferred = require('../../deferred')
+ , isPromise = require('../../is-promise')
+ , assimilate = require('../../assimilate')
, call = Function.prototype.call
, hasOwnProperty = Object.prototype.hasOwnProperty
+ , resolve = deferred.resolve
, Reduce;
Reduce = function (list, cb, initial, initialized) {
@@ -19,17 +20,18 @@ Reduce = function (list, cb, initial, initialized) {
this.initialized = initialized;
this.length = list.length >>> 0;
+ initial = assimilate(initial);
if (isPromise(initial)) {
if (!initial.resolved) {
assign(this, deferred());
initial.end(function (initial) {
this.value = initial;
this.init();
- }.bind(this), this.resolve);
+ }.bind(this), this.reject);
return this.promise;
}
this.value = initial.value;
- if (isError(this.value)) return initial;
+ if (initial.failed) return initial;
} else {
this.value = initial;
}
@@ -49,7 +51,7 @@ Reduce.prototype = {
if (!this.initialized) {
throw new Error("Reduce of empty array with no initial value");
}
- return this.resolve ? this.resolve(this.value) : deferred(this.value);
+ return this.resolve ? this.resolve(this.value) : resolve(this.value);
}
if (!this.promise) assign(this, deferred());
this.processCb = this.processCb.bind(this);
@@ -68,25 +70,22 @@ Reduce.prototype = {
}
},
process: function () {
- var value = this.list[this.current];
+ var value = assimilate(this.list[this.current]);
if (isPromise(value)) {
if (!value.resolved) {
- value.end(function (result) {
+ value.done(function (result) {
result = this.processCb(result);
if (this.state !== 'value') return;
this.processValue(result);
if (!this.state) this.continue();
- }.bind(this), this.resolve);
+ }.bind(this), this.reject);
return;
}
- value = value.value;
- if (isError(value)) {
- this.resolve(value);
+ if (value.failed) {
+ this.reject(value.value);
return;
}
- } else if (isError(value) && !this.cb) {
- this.resolve(value);
- return;
+ value = value.value;
}
this.state = 'cb';
return value;
@@ -102,24 +101,25 @@ Reduce.prototype = {
value = call.call(this.cb, undefined, this.value, value, this.current,
this.list);
} catch (e) {
- this.resolve(e);
+ this.reject(e);
return;
}
+ value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
- value.end(function (result) {
+ value.done(function (result) {
this.state = 'value';
this.processValue(result);
if (!this.state) this.continue();
- }.bind(this), this.resolve);
+ }.bind(this), this.reject);
+ return;
+ }
+ if (value.failed) {
+ this.reject(value.value);
return;
}
value = value.value;
}
- if (isError(value)) {
- this.resolve(value);
- return;
- }
}
this.state = 'value';
return value;
41 lib/ext/array/some.js → ext/array/some.js
View
@@ -2,14 +2,15 @@
'use strict';
-var isError = require('es5-ext/error/is-error')
- , assign = require('es5-ext/object/assign')
- , value = require('es5-ext/object/valid-value')
- , callable = require('es5-ext/object/valid-callable')
- , deferred = require('../../deferred')
- , isPromise = require('../../is-promise')
+var assign = require('es5-ext/object/assign')
+ , value = require('es5-ext/object/valid-value')
+ , callable = require('es5-ext/object/valid-callable')
+ , deferred = require('../../deferred')
+ , isPromise = require('../../is-promise')
+ , assimilate = require('../../assimilate')
, call = Function.prototype.call
+ , resolve = deferred.resolve
, Some;
Some = function (list, cb, context) {
@@ -28,26 +29,23 @@ Some = function (list, cb, context) {
}
++this.current;
}
- return deferred(false);
+ return resolve(false);
};
Some.prototype = {
current: 0,
process: function () {
- var value = this.list[this.current];
+ var value = assimilate(this.list[this.current]);
if (isPromise(value)) {
if (!value.resolved) {
- value.end(this.processCb, this.resolve);
+ value.done(this.processCb, this.reject);
return;
}
- value = value.value;
- if (isError(value)) {
- this.resolve(value);
+ if (value.failed) {
+ this.reject(value.value);
return;
}
- } else if (isError(value) && !this.cb) {
- this.resolve(value);
- return;
+ value = value.value;
}
this.processCb(value);
},
@@ -57,20 +55,21 @@ Some.prototype = {
value = call.call(this.cb, this.context, value, this.current,
this.list);
} catch (e) {
- this.resolve(e);
+ this.reject(e);
return;
}
+ value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
- value.end(this.processValue, this.resolve);
+ value.done(this.processValue, this.reject);
+ return;
+ }
+ if (value.failed) {
+ this.reject(value.value);
return;
}
value = value.value;
}
- if (isError(value)) {
- this.resolve(value);
- return;
- }
}
this.processValue(value);
},
2  lib/ext/function/call-async.js → ext/function/call-async.js
View
@@ -42,7 +42,7 @@ callAsync = function (fn, length, context, args) {
try {
applyFn.call(context, fn, args, def);
} catch (e) {
- def.resolve(e);
+ def.reject(e);
throw e;
}
return def.promise;
8 lib/ext/function/delay.js → ext/function/delay.js
View
@@ -8,12 +8,13 @@ var apply = Function.prototype.apply
, delayed;
-delayed = function (fn, args, resolve) {
+delayed = function (fn, args, resolve, reject) {
var value;
try {
value = apply.call(fn, this, args);
} catch (e) {
- value = e;
+ reject(e);
+ return;
}
resolve(value);
};
@@ -23,7 +24,8 @@ module.exports = function (timeout) {
fn = callable(this);
result = function () {
var def = deferred();
- setTimeout(delayed.bind(this, fn, arguments, def.resolve), timeout);
+ setTimeout(delayed.bind(this, fn, arguments, def.resolve, def.reject),
+ timeout);
return def.promise;
};
result.returnsPromise = true;
29 lib/ext/function/gate.js → ext/function/gate.js
View
@@ -5,22 +5,23 @@
'use strict';
-var toUint = require('es5-ext/number/to-uint')
- , callable = require('es5-ext/object/valid-callable')
- , eeUnify = require('event-emitter/lib/unify')
- , deferred = require('../../deferred')
- , isPromise = require('../../is-promise')
+var toUint = require('es5-ext/number/to-uint')
+ , callable = require('es5-ext/object/valid-callable')
+ , eeUnify = require('event-emitter/lib/unify')
+ , deferred = require('../../deferred')
+ , isPromise = require('../../is-promise')
+ , assimilate = require('../../assimilate')
+ , resolve = deferred.resolve, reject = deferred.reject
, apply = Function.prototype.apply, max = Math.max
-
- , reject;
+ , gateReject;
require('../promise/finally');
-reject = function () {
+gateReject = function () {
var e = new Error("Too many calls");
e.type = 'deferred-gate-rejected';
- return deferred(e);
+ return reject(e);
};
module.exports = function (cLimit, qLimit) {
@@ -36,8 +37,12 @@ module.exports = function (cLimit, qLimit) {
try {
r = apply.call(fn, thisArg, args);
} catch (e) {
- r = e;
+ if (!def) return reject(e);
+ def.reject(e);
+ unload();
+ return;
}
+ r = assimilate(r);
if (isPromise(r)) {
if (def) eeUnify(def.promise, r);
if (!r.resolved) {
@@ -47,7 +52,7 @@ module.exports = function (cLimit, qLimit) {
}
r = r.value;
}
- if (!def) return deferred(r);
+ if (!def) return resolve(r);
def.resolve(r);
unload();
};
@@ -70,7 +75,7 @@ module.exports = function (cLimit, qLimit) {
queue.push([this, arguments, def]);
return def.promise;
}
- return reject();
+ return gateReject();
}
return run(this, arguments);
};
25 lib/ext/function/promisify-sync.js → ext/function/promisify-sync.js
View
@@ -11,12 +11,13 @@ var callable = require('es5-ext/object/valid-callable')
, applyFn;
-applyFn = function (fn, args, resolve) {
+applyFn = function (fn, args, resolve, reject) {
var value;
try {
value = apply.call(fn, this, args);
} catch (e) {
- value = e;
+ reject(e);
+ return;
}
resolve(value);
};
@@ -24,27 +25,21 @@ applyFn = function (fn, args, resolve) {
module.exports = function (length) {
var fn, result;
fn = callable(this);
- if (fn.returnsPromise) {
- return fn;
- }
- if (length != null) {
- length = length >>> 0;
- }
+ if (fn.returnsPromise) return fn;
+ if (length != null) length = length >>> 0;
result = function () {
var args, def;
args = processArguments(arguments, length);
if (isPromise(args)) {
- if (args.failed) {
- return args;
- }
+ if (args.failed) return args;
def = deferred();
- args.end(function (args) {
- apply.call(this, fn, args, def.resolve);
- }.bind(this), def.resolve);
+ args.done(function (args) {
+ applyFn.call(this, fn, args, def.resolve, def.reject);
+ }.bind(this), def.reject);
} else {
def = deferred();
- applyFn.call(this, fn, args, def.resolve);
+ applyFn.call(this, fn, args, def.resolve, def.reject);
}
return def.promise;
0  lib/ext/function/promisify.js → ext/function/promisify.js
View
File renamed without changes
31 lib/ext/promise/_array.js → ext/promise/_array.js
View
@@ -3,37 +3,38 @@
'use strict';
var callable = require('es5-ext/object/valid-callable')
- , deferred = require('../../deferred');
+ , deferred = require('../../deferred')
+
+ , reject = deferred.reject;
module.exports = function (name, ext) {
deferred.extend(name, function (cb) {
var def;
((cb == null) || callable(cb));
- if (!this.pending) {
- this.pending = [];
- }
+ if (!this.pending) this.pending = [];
def = deferred();
- this.pending.push(name, [arguments, def.resolve]);
+ this.pending.push(name, [arguments, def.resolve, def.reject]);
return def.promise;
- }, function (args, resolve) {
+ }, function (args, resolve, reject) {
var result;
if (this.failed) {
- resolve(this.value);
- } else {
- try {
- result = ext.apply(this.value, args);
- } catch (e) {
- result = e;
- }
- resolve(result);
+ reject(this.value);
+ return;
+ }
+ try {
+ result = ext.apply(this.value, args);
+ } catch (e) {
+ reject(e);
+ return;
}
+ resolve(result);
}, function (cb) {
((cb == null) || callable(cb));
if (this.failed) return this;
try {
return ext.apply(this.value, arguments);
} catch (e) {
- return deferred(e);
+ return reject(e);
}
});
};
0  lib/ext/promise/aside.js → ext/promise/aside.js
View
File renamed without changes
29 lib/ext/promise/catch.js → ext/promise/catch.js
View
@@ -9,16 +9,18 @@
var isCallable = require('es5-ext/object/is-callable')
, validValue = require('es5-ext/object/valid-value')
, deferred = require('../../deferred')
- , isPromise = require('../../is-promise');
+ , isPromise = require('../../is-promise')
+
+ , resolve = deferred.resolve, reject = deferred.reject;
deferred.extend('catch', function (cb) {
var def;
validValue(cb);
if (!this.pending) this.pending = [];
def = deferred();
- this.pending.push('catch', [cb, def.resolve]);
+ this.pending.push('catch', [cb, def.resolve, def.reject]);
return def.promise;
-}, function (cb, resolve) {
+}, function (cb, resolve, reject) {
var value;
if (!this.failed) {
resolve(this.value);
@@ -26,11 +28,18 @@ deferred.extend('catch', function (cb) {
}
if (isCallable(cb)) {
if (isPromise(cb)) {
- if (cb.resolved) resolve(cb.value);
- else cb.done(resolve, resolve);
+ if (cb.resolved) {
+ if (cb.failed) reject(cb.value);
+ else resolve(cb.value);
+ } else {
+ cb.done(resolve, reject);
+ }
+ return;
+ }
+ try { value = cb(this.value); } catch (e) {
+ reject(e);
return;
}
- try { value = cb(this.value); } catch (e) { value = e; }
resolve(value);
return;
}
@@ -41,8 +50,10 @@ deferred.extend('catch', function (cb) {
if (!this.failed) return this;
if (isCallable(cb)) {
if (isPromise(cb)) return cb;
- try { value = cb(this.value); } catch (e) { value = e; }
- return deferred(value);
+ try { value = cb(this.value); } catch (e) {
+ return reject(e);
+ }
+ return resolve(value);
}
- return deferred(cb);
+ return resolve(cb);
});
33 lib/ext/promise/cb.js → ext/promise/cb.js
View
@@ -25,42 +25,27 @@ var callable = require('es5-ext/object/valid-callable')
, deferred = require('../../deferred');
deferred.extend('cb', function (cb) {
- if (cb == null) {
- return this;
- }
+ if (cb == null) return this;
callable(cb);
nextTick(function () {
if (this.resolved) {
- if (this.failed) {
- cb(this.value);
- } else {
- cb(null, this.value);
- }
+ if (this.failed) cb(this.value);
+ else cb(null, this.value);
} else {
- if (!this.pending) {
- this.pending = [];
- }
+ if (!this.pending) this.pending = [];
this.pending.push('cb', [cb]);
}
}.bind(this));
return this;
}, function (cb) {
- if (this.failed) {
- cb(this.value);
- } else {
- cb(null, this.value);
- }
+ if (this.failed) cb(this.value);
+ else cb(null, this.value);
}, function (cb) {
- if (cb == null) {
- return this;
- }
+ if (cb == null) return this;
callable(cb);
nextTick(function () {
- if (this.failed) {
- cb(this.value);
- } else {
- cb(null, this.value);
- }
+ if (this.failed) cb(this.value);
+ else cb(null, this.value);
}.bind(this));
return this;
});
0  lib/ext/promise/finally.js → ext/promise/finally.js
View
File renamed without changes
28 lib/ext/promise/get.js → ext/promise/get.js
View
@@ -9,41 +9,37 @@
var value = require('es5-ext/object/valid-value')
, deferred = require('../../deferred')
- , reduce = Array.prototype.reduce;
+ , reduce = Array.prototype.reduce
+ , resolve = deferred.resolve, reject = deferred.reject;
deferred.extend('get', function (/*…name*/) {
var def;
- if (!this.pending) {
- this.pending = [];
- }
+ if (!this.pending) this.pending = [];
def = deferred();
- this.pending.push('get', [arguments, def.resolve]);
+ this.pending.push('get', [arguments, def.resolve, def.reject]);
return def.promise;
-}, function (args, resolve) {
+}, function (args, resolve, reject) {
var result;
- if (this.failed) {
- resolve(this.value);
- }
+ if (this.failed) reject(this.value);
try {
result = reduce.call(args, function (obj, key) {
return value(obj)[String(key)];
}, this.value);
} catch (e) {
- result = e;
+ reject(e);
+ return;
}
- return resolve(result);
+ resolve(result);
}, function (/*…name*/) {
var result;
- if (this.failed) {
- return this;
- }
+ if (this.failed) return this;
try {
result = reduce.call(arguments, function (obj, key) {
return value(obj)[String(key)];
}, this.value);
} catch (e) {
- result = e;
+ return reject(e);
}
- return deferred(result);
+ return resolve(result);
});
52 lib/ext/promise/invoke-async.js → ext/promise/invoke-async.js
View
@@ -16,16 +16,18 @@ var toArray = require('es5-ext/array/to-array')
, processArguments = require('../_process-arguments')
, slice = Array.prototype.slice, apply = Function.prototype.apply
+ , reject = deferred.reject
, applyFn;
-applyFn = function (fn, args, resolve) {
+applyFn = function (fn, args, resolve, reject) {
var result;
if (fn.returnsPromise) {
try {
result = apply.call(fn, this, args);
} catch (e) {
- result = e;
+ reject(e);
+ return;
}
return resolve(result);
}
@@ -33,33 +35,31 @@ applyFn = function (fn, args, resolve) {
if (error == null) {
resolve((arguments.length > 2) ? slice.call(arguments, 1) : result);
} else {
- resolve(error);
+ reject(error);
}
});
try {
apply.call(fn, this, args);
} catch (e2) {
- resolve(e2);
+ reject(e2);
}
};
deferred.extend('invokeAsync', function (method/*, …args*/) {
var def;
- if (!this.pending) {
- this.pending = [];
- }
+ if (!this.pending) this.pending = [];
def = deferred();
- this.pending.push('invokeAsync', [arguments, def.resolve]);
+ this.pending.push('invokeAsync', [arguments, def.resolve, def.reject]);
return def.promise;
-}, function (args, resolve) {
+}, function (args, resolve, reject) {
var fn;
if (this.failed) {
- resolve(this);
+ reject(this);
return;
}
if (this.value == null) {
- resolve(new TypeError("Cannot use null or undefined"));
+ reject(new TypeError("Cannot use null or undefined"));
return;
}
@@ -67,7 +67,7 @@ deferred.extend('invokeAsync', function (method/*, …args*/) {
if (!isCallable(fn)) {
fn = String(fn);
if (!isCallable(this.value[fn])) {
- resolve(new TypeError(fn + " is not a function"));
+ reject(new TypeError(fn + " is not a function"));
return;
}
fn = this.value[fn];
@@ -76,29 +76,27 @@ deferred.extend('invokeAsync', function (method/*, …args*/) {
args = processArguments(slice.call(args, 1));
if (isPromise(args)) {
if (args.failed) {
- resolve(args);
+ reject(args);
return;
}
- args.end(function (args) {
- applyFn.call(this, fn, args, resolve);
- }.bind(this.value), resolve);
+ args.done(function (args) {
+ applyFn.call(this, fn, args, resolve, reject);
+ }.bind(this.value), reject);
} else {
- applyFn.call(this.value, fn, args, resolve);
+ applyFn.call(this.value, fn, args, resolve, reject);
}
}, function (method/*, …args*/) {
var args, def;
- if (this.failed) {
- return this;
- }
+ if (this.failed) return this;
if (this.value == null) {
- return deferred(new TypeError("Cannot use null or undefined"));
+ return reject(new TypeError("Cannot use null or undefined"));
}
if (!isCallable(method)) {
method = String(method);
if (!isCallable(this.value[method])) {
- return deferred(new TypeError(method + " is not a function"));
+ return reject(new TypeError(method + " is not a function"));
}
method = this.value[method];
}
@@ -107,14 +105,14 @@ deferred.extend('invokeAsync', function (method/*, …args*/) {
if (isPromise(args)) {
if (args.failed) return args;
def = deferred();
- args.end(function (args) {
- applyFn.call(this, method, args, def.resolve);
- }.bind(this.value), def.resolve);
+ args.done(function (args) {
+ applyFn.call(this, method, args, def.resolve, def.reject);
+ }.bind(this.value), def.reject);
} else if (!method.returnsPromise) {
def = deferred();
- applyFn.call(this.value, method, args, def.resolve);
+ applyFn.call(this.value, method, args, def.resolve, def.reject);
} else {
- return applyFn.call(this.value, method, args, deferred);
+ return applyFn.call(this.value, method, args, deferred, reject);
}
return def.promise;
});
50 lib/ext/promise/invoke.js → ext/promise/invoke.js
View
@@ -13,34 +13,34 @@ var isCallable = require('es5-ext/object/is-callable')
, processArguments = require('../_process-arguments')
, slice = Array.prototype.slice, apply = Function.prototype.apply
-
+ , reject = deferred.reject
, applyFn;
-applyFn = function (fn, args) {
+applyFn = function (fn, args, resolve, reject) {
+ var value;
try {
- return apply.call(fn, this, args);
+ value = apply.call(fn, this, args);
} catch (e) {
- return e;
+ return reject(e);
}
+ return resolve(value);
};
deferred.extend('invoke', function (method/*, …args*/) {
var def;
- if (!this.pending) {
- this.pending = [];
- }
+ if (!this.pending) this.pending = [];
def = deferred();
- this.pending.push('invoke', [arguments, def.resolve]);
+ this.pending.push('invoke', [arguments, def.resolve, def.reject]);
return def.promise;
-}, function (args, resolve) {
+}, function (args, resolve, reject) {
var fn;
if (this.failed) {
- resolve(this);
+ reject(this);
return;
}
if (this.value == null) {
- resolve(new TypeError("Cannot use null or undefined"));
+ reject(new TypeError("Cannot use null or undefined"));
return;
}
@@ -48,7 +48,7 @@ deferred.extend('invoke', function (method/*, …args*/) {
if (!isCallable(fn)) {
fn = String(fn);
if (!isCallable(this.value[fn])) {
- resolve(new TypeError(fn + " is not a function"));
+ reject(new TypeError(fn + " is not a function"));
return;
}
fn = this.value[fn];
@@ -57,29 +57,27 @@ deferred.extend('invoke', function (method/*, …args*/) {
args = processArguments(slice.call(args, 1));
if (isPromise(args)) {
if (args.failed) {
- resolve(args);
+ reject(args.value);
return;
}
- args.end(function (args) {
- resolve(applyFn.call(this, fn, args));
- }.bind(this.value), resolve);
+ args.done(function (args) {
+ applyFn.call(this, fn, args, resolve, reject);
+ }.bind(this.value), reject);
} else {
- resolve(applyFn.call(this.value, fn, args));
+ applyFn.call(this.value, fn, args, resolve, reject);
}
}, function (method/*, …args*/) {
var args, def;
- if (this.failed) {
- return this;
- }
+ if (this.failed) return this;
if (this.value == null) {
- return deferred(new TypeError("Cannot use null or undefined"));
+ return reject(new TypeError("Cannot use null or undefined"));
}
if (!isCallable(method)) {
method = String(method);
if (!isCallable(this.value[method])) {
- return deferred(new TypeError(method + " is not a function"));
+ return reject(new TypeError(method + " is not a function"));
}
method = this.value[method];
}
@@ -88,10 +86,10 @@ deferred.extend('invoke', function (method/*, …args*/) {
if (isPromise(args)) {
if (args.failed) return args;
def = deferred();
- args.end(function (args) {
- def.resolve(applyFn.call(this, method, args));
- }.bind(this.value), def.resolve);
+ args.done(function (args) {
+ applyFn.call(this, method, args, def.resolve, def.reject);
+ }.bind(this.value), def.reject);
return def.promise;
}
- return deferred(applyFn.call(this.value, method, args));
+ return applyFn.call(this.value, method, args, deferred, reject);
});
0  lib/ext/promise/map.js → ext/promise/map.js
View
File renamed without changes
41 lib/ext/promise/match.js → ext/promise/match.js
View
@@ -11,42 +11,41 @@ var spread = require('es5-ext/function/#/spread')
, callable = require('es5-ext/object/valid-callable')
, isCallable = require('es5-ext/object/is-callable')
, isPromise = require('../../is-promise')
- , deferred = require('../../deferred');
+ , deferred = require('../../deferred')
+
+ , resolve = deferred.resolve, reject = deferred.reject;
deferred.extend('match', function (win, fail) {
var def;
((win == null) || callable(win));
- if (!win && (fail == null)) {
- return this;
- }
- if (!this.pending) {
- this.pending = [];
- }
+ if (!win && (fail == null)) return this;
+ if (!this.pending) this.pending = [];
def = deferred();
- this.pending.push('match', [win, fail, def.resolve]);
+ this.pending.push('match', [win, fail, def.resolve, def.reject]);
return def.promise;
-}, function (win, fail, resolve) {
+}, function (win, fail, resolve, reject) {
var cb, value;
cb = this.failed ? fail : win;
if (cb == null) {
- resolve(this);
+ if (this.failed) reject(this.value);
+ else resolve(this.value);
}
if (isCallable(cb)) {
if (isPromise(cb)) {
if (cb.resolved) {
- resolve(cb.value);
+ if (cb.failed) reject(cb.value);
+ else resolve(cb.value);
} else {
- cb.end(resolve, resolve);
+ cb.done(resolve, reject);
}
return;
}
- if (!this.failed) {
- cb = spread.call(cb);
- }
+ if (!this.failed) cb = spread.call(cb);
try {
value = cb(this.value);
} catch (e) {
- value = e;
+ reject(e);
+ return;
}
resolve(value);
} else {
@@ -55,18 +54,16 @@ deferred.extend('match', function (win, fail) {
}, function (win, fail) {
var cb, value;
cb = this.failed ? fail : win;
- if (cb == null) {
- return this;
- }
+ if (cb == null) return this;
if (isCallable(cb)) {
if (isPromise(cb)) return cb;
if (!this.failed) cb = spread.call(cb);
try {
value = cb(this.value);
} catch (e) {
- value = e;
+ return reject(e);
}
- return deferred(value);
+ return resolve(value);
}
- return deferred(cb);
+ return resolve(cb);
});
0  lib/ext/promise/reduce.js → ext/promise/reduce.js
View
File renamed without changes
0  lib/ext/promise/some.js → ext/promise/some.js
View
File renamed without changes
0  lib/index.js → index.js
View
File renamed without changes
0  lib/invoke-async.js → invoke-async.js
View
File renamed without changes
0  lib/is-promise.js → is-promise.js
View
File renamed without changes
0  lib/monitor.js → monitor.js
View
File renamed without changes
21 package.json
View
@@ -1,7 +1,8 @@
{
"name": "deferred",
- "version": "0.6.8",
+ "version": "0.7.0",
"description": "Modular and fast Promises implementation",
+ "author": "Mariusz Nowak <medyk@medikoo.com> (http://www.medikoo.com/)",
"keywords": [
"async",
"asynchronous",
@@ -13,31 +14,21 @@
"promises",
"continuations"
],
- "author": "Mariusz Nowak <medikoo+deferred@medikoo.com> (http://www.medikoo.com/)",</