Comparing version 0.5.3 to 0.5.4
@@ -10,3 +10,3 @@ // Returns function that returns deferred or promise object. | ||
// 3. If invoked with more than one arguments then promise that resolves with | ||
// array of all resolved arguments iss returned. | ||
// array of all resolved arguments is returned. | ||
@@ -13,0 +13,0 @@ 'use strict'; |
@@ -5,9 +5,9 @@ // Promise aware Array's map | ||
var every = Array.prototype.every | ||
, call = Function.prototype.call | ||
, assertNotNull = require('es5-ext/lib/assert-not-null') | ||
, isError = require('es5-ext/lib/Error/is-error') | ||
, assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, deferred = require('../../deferred') | ||
, isPromise = require('../../is-promise'); | ||
var every = Array.prototype.every | ||
, call = Function.prototype.call | ||
, isError = require('es5-ext/lib/Error/is-error') | ||
, callable = require('es5-ext/lib/Object/valid-callable') | ||
, value = require('es5-ext/lib/Object/valid-value') | ||
, deferred = require('../../deferred') | ||
, isPromise = require('../../is-promise'); | ||
@@ -100,7 +100,5 @@ var Map = function (list, cb, thisArg, limit) { | ||
module.exports = function (cb, thisArg, limit) { | ||
var result, iterator, d; | ||
assertNotNull(this); | ||
if (cb != null) { | ||
assertCallable(cb); | ||
} | ||
var iterator; | ||
value(this); | ||
(cb == null) || callable(cb); | ||
every.call(this, (iterator = new Map(this, cb, thisArg, limit)).iterate, | ||
@@ -107,0 +105,0 @@ iterator); |
@@ -5,13 +5,19 @@ // Promise aware Array's reduce | ||
var every = Array.prototype.every | ||
, call = Function.prototype.call | ||
, assertNotNull = require('es5-ext/lib/assert-not-null') | ||
, isError = require('es5-ext/lib/Error/is-error') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, create = require('es5-ext/lib/Object/prototype/plain-create') | ||
, isPromise = require('../../is-promise') | ||
, promise = require('../../promise'); | ||
var every = Array.prototype.every | ||
, call = Function.prototype.call | ||
, isError = require('es5-ext/lib/Error/is-error') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, callable = require('es5-ext/lib/Object/valid-callable') | ||
, value = require('es5-ext/lib/Object/valid-value') | ||
, isPromise = require('../../is-promise') | ||
, promise = require('../../promise'); | ||
var proto = { | ||
var Iterator = function (initialized, current, cb, list) { | ||
this.initialized = initialized; | ||
this.current = current; | ||
this.cb = cb; | ||
this.list = list; | ||
}; | ||
Iterator.prototype = { | ||
iterate: function self(value, index) { | ||
@@ -45,3 +51,3 @@ if (!this.initialized) { | ||
processCb: function (accumulator, index, value) { | ||
return silent.call(this.cb, accumulator, value, index, this.list); | ||
return silent.call(this.cb)(accumulator, value, index, this.list); | ||
} | ||
@@ -52,20 +58,17 @@ }; | ||
var iterator; | ||
assertNotNull(this); | ||
if (cb != null) { | ||
assertCallable(cb); | ||
} | ||
value(this); | ||
(cb == null) || callable(cb); | ||
if (initial && isError(initial)) { | ||
return promise(initial); | ||
} | ||
every.call(this, (iterator = create.call(proto, { | ||
initialized: (arguments.length > 1), | ||
current: initial, | ||
cb: cb, | ||
list: this | ||
})).iterate, iterator); | ||
iterator = new Iterator((arguments.length > 1), initial, cb, this); | ||
every.call(this, iterator.iterate, iterator); | ||
if (!iterator.initialized) { | ||
throw new Error("Reduce of empty array with no initial value"); | ||
} | ||
return promise(iterator.current); | ||
}; |
@@ -5,15 +5,14 @@ // Delay function execution, return promise for delayed function result | ||
var silent = require('es5-ext/lib/Function/prototype/silent') | ||
, assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, deferred = require('../../deferred') | ||
var silent = require('es5-ext/lib/Function/prototype/silent') | ||
, callable = require('es5-ext/lib/Object/valid-callable') | ||
, deferred = require('../../deferred') | ||
, delayed; | ||
delayed = function (fn, args, resolve) { | ||
resolve(silent.apply(fn.bind(this), args)); | ||
resolve(silent.call(fn).apply(this, args)); | ||
}; | ||
module.exports = function (timeout) { | ||
var fn; | ||
assertCallable(this); | ||
fn = this; | ||
var fn = callable(this); | ||
return function () { | ||
@@ -20,0 +19,0 @@ var d = deferred(); |
@@ -5,14 +5,13 @@ // Promisify synchronous function | ||
var isArray = Array.isArray | ||
, slice = Array.prototype.slice | ||
, some = Array.prototype.some | ||
, assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, deferred = require('../../deferred') | ||
, isPromise = require('../../is-promise'); | ||
var isArray = Array.isArray | ||
, slice = Array.prototype.slice | ||
, some = Array.prototype.some | ||
, callable = require('es5-ext/lib/Object/valid-callable') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, deferred = require('../../deferred') | ||
, isPromise = require('../../is-promise'); | ||
module.exports = function (length) { | ||
var fn, args; | ||
assertCallable(this); | ||
fn = this; | ||
fn = callable(this); | ||
if (length != null) { | ||
@@ -31,5 +30,5 @@ length = length >>> 0; | ||
} else { | ||
return deferred(silent.apply(fn.bind(this), args)); | ||
return deferred(silent.call(fn).apply(this, args)); | ||
} | ||
}; | ||
}; |
@@ -5,13 +5,12 @@ // Promisify asynchronous function | ||
var isArray = Array.isArray | ||
, some = Array.prototype.some | ||
, assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, apply = require('../utils/apply-async') | ||
, deferred = require('../../deferred') | ||
, isPromise = require('../../is-promise'); | ||
var isArray = Array.isArray | ||
, some = Array.prototype.some | ||
, callable = require('es5-ext/lib/Object/valid-callable') | ||
, apply = require('../utils/apply-async') | ||
, deferred = require('../../deferred') | ||
, isPromise = require('../../is-promise'); | ||
module.exports = function (length) { | ||
var fn, args; | ||
assertCallable(this); | ||
fn = this; | ||
fn = callable(this); | ||
if (length != null) { | ||
@@ -18,0 +17,0 @@ length = length >>> 0; |
@@ -22,3 +22,3 @@ // 'cb' - Promise extension | ||
var assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
var callable = require('es5-ext/lib/Object/valid-callable') | ||
@@ -28,4 +28,4 @@ , b; | ||
require('../../extend')('cb', function (win, fail) { | ||
(win != null) && assertCallable(win); | ||
(fail != null) && assertCallable(fail); | ||
(win == null) || callable(win); | ||
(fail == null) || callable(fail); | ||
if (win || fail) { | ||
@@ -32,0 +32,0 @@ if (this._base.resolved) { |
@@ -9,7 +9,7 @@ // 'get' - Promise extension | ||
var reduce = Array.prototype.reduce | ||
, assertNotNull = require('es5-ext/lib/assert-not-null'); | ||
var reduce = Array.prototype.reduce | ||
, value = require('es5-ext/lib/Object/valid-value'); | ||
require('../../extend')('get', [assertNotNull], function (args, resolve) { | ||
var value; | ||
require('../../extend')('get', [value], function (args, resolve) { | ||
var result; | ||
if (this.failed) { | ||
@@ -19,5 +19,4 @@ return resolve(this.promise); | ||
try { | ||
value = reduce.call(args, function (obj, key) { | ||
assertNotNull(obj); | ||
return obj[String(key)]; | ||
result = reduce.call(args, function (obj, key) { | ||
return value(obj)[String(key)]; | ||
}, this.value); | ||
@@ -27,5 +26,5 @@ } catch (e) { | ||
} | ||
return resolve(value); | ||
return resolve(result); | ||
}); | ||
module.exports = require('../../deferred'); |
@@ -12,8 +12,8 @@ // 'invokeAsync' - Promise extension | ||
var slice = Array.prototype.slice | ||
, assertNotNull = require('es5-ext/lib/assert-not-null') | ||
, apply = require('../utils/apply-async') | ||
, invoke = require('./utils/invoke'); | ||
var slice = Array.prototype.slice | ||
, value = require('es5-ext/lib/Object/valid-value') | ||
, apply = require('../utils/apply-async') | ||
, invoke = require('./utils/invoke'); | ||
require('../../extend')('invokeAsync', [assertNotNull], | ||
require('../../extend')('invokeAsync', [value], | ||
function (args, resolve) { | ||
@@ -20,0 +20,0 @@ var fn = args[0]; |
@@ -1,4 +0,4 @@ | ||
// 'invokeSync' - Promise extension | ||
// 'invoke' - Promise extension | ||
// | ||
// promise.invokeSync(name[, arg0[, arg1[, ...]]]) | ||
// promise.invoke(name[, arg0[, arg1[, ...]]]) | ||
// | ||
@@ -10,13 +10,13 @@ // On resolved object calls method that returns immediately. | ||
var slice = Array.prototype.slice | ||
, assertNotNull = require('es5-ext/lib/assert-not-null') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, invoke = require('./utils/invoke') | ||
var slice = Array.prototype.slice | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, value = require('es5-ext/lib/Object/valid-value') | ||
, invoke = require('./utils/invoke') | ||
, apply; | ||
apply = function (fn, args, resolve) { | ||
return resolve(silent.apply(fn.bind(this), args)); | ||
return resolve(silent.call(fn).apply(this, args)); | ||
}; | ||
require('../../extend')('invoke', [assertNotNull], | ||
require('../../extend')('invoke', [value], | ||
function (args, resolve) { | ||
@@ -23,0 +23,0 @@ var fn = args[0]; |
@@ -1,12 +0,12 @@ | ||
// (DRY) Used by promise extensions that are based on array extensions | ||
// Used by promise extensions that are based on array extensions. | ||
'use strict'; | ||
var assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, extend = require('../../../extend'); | ||
var callable = require('es5-ext/lib/Object/valid-callable') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, extend = require('../../../extend'); | ||
module.exports = function (name, ext) { | ||
extend(name, [function (cb) { | ||
return (cb != null) && assertCallable(cb); | ||
(cb == null) || callable(cb); | ||
}], function (args, resolve) { | ||
@@ -17,6 +17,6 @@ var cb, cbs; | ||
} else { | ||
return resolve(silent.call(ext.bind(this.value, | ||
args[0], args[1], args[2]))); | ||
return resolve(silent.call(ext).call(this.value, | ||
args[0], args[1], args[2])); | ||
} | ||
}); | ||
}; |
@@ -6,6 +6,6 @@ // Asynchronous function handler | ||
var slice = Array.prototype.slice | ||
, toArray = require('es5-ext/lib/Object/prototype/to-array'); | ||
, toArray = require('es5-ext/lib/Array/from'); | ||
module.exports = function (fn, args, resolve, length) { | ||
args = (length != null) ? slice.call(args, 0, length) : toArray.call(args); | ||
args = (length != null) ? slice.call(args, 0, length) : toArray(args); | ||
while (args.length < length) { | ||
@@ -12,0 +12,0 @@ args.push(undefined); |
@@ -13,7 +13,7 @@ // Through this function we setup extensions on promise objects. | ||
var forEach = Array.prototype.forEach | ||
, assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, isCallable = require('es5-ext/lib/Object/is-callable') | ||
, deferred = require('./deferred') | ||
, promise = require('./promise') | ||
var forEach = Array.prototype.forEach | ||
, callable = require('es5-ext/lib/Object/valid-callable') | ||
, isCallable = require('es5-ext/lib/Object/is-callable') | ||
, deferred = require('./deferred') | ||
, promise = require('./promise') | ||
@@ -23,6 +23,6 @@ , front = promise.front, back = promise.back; | ||
module.exports = function (name, f, b) { | ||
(b != null) && assertCallable(b); | ||
(b == null) || callable(b); | ||
if (!isCallable(f)) { | ||
f && forEach.call(f, function (validator) { | ||
(validator != null) && assertCallable(validator); | ||
(validator == null) || callable(validator); | ||
}); | ||
@@ -29,0 +29,0 @@ if (!b) { |
@@ -7,8 +7,10 @@ // This construct deferred with all needed goodies that are being exported | ||
var call = Function.prototype.call | ||
, merge = require('es5-ext/lib/Object/prototype/merge'); | ||
var call = Function.prototype.call | ||
, extend = require('es5-ext/lib/Object/extend'); | ||
module.exports = merge.call(require('./deferred'), { | ||
module.exports = extend(require('./deferred'), { | ||
isPromise: require('./is-promise'), | ||
delay: call.bind(require('./ext/function/delay')), | ||
gate: call.bind(require('./ext/function/gate')), | ||
monitor: require('./monitor'), | ||
promisify: call.bind(require('./ext/function/promisify')), | ||
@@ -15,0 +17,0 @@ promisifySync: call.bind(require('./ext/function/promisify-sync')), |
@@ -7,14 +7,14 @@ // Promise function implementation. Unresolved and resolved logic. | ||
var push = Array.prototype.push | ||
, apply = Function.prototype.apply | ||
, defineProperty = Object.defineProperty | ||
, keys = Object.keys | ||
, isError = require('es5-ext/lib/Error/is-error') | ||
, noop = require('es5-ext/lib/Function/noop') | ||
, match = require('es5-ext/lib/Function/prototype/match') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, assertCallable = require('es5-ext/lib/Object/assert-callable') | ||
, dscr = require('es5-ext/lib/Object/descriptor') | ||
, isCallable = require('es5-ext/lib/Object/is-callable') | ||
, isPromise = require('./is-promise') | ||
var push = Array.prototype.push | ||
, apply = Function.prototype.apply | ||
, defineProperty = Object.defineProperty | ||
, keys = Object.keys | ||
, isError = require('es5-ext/lib/Error/is-error') | ||
, noop = require('es5-ext/lib/Function/noop') | ||
, match = require('es5-ext/lib/Function/prototype/match') | ||
, silent = require('es5-ext/lib/Function/prototype/silent') | ||
, callable = require('es5-ext/lib/Object/valid-callable') | ||
, dscr = require('es5-ext/lib/Object/descriptor') | ||
, isCallable = require('es5-ext/lib/Object/is-callable') | ||
, isPromise = require('./is-promise') | ||
@@ -26,4 +26,4 @@ , front, back, Resolved, Unresolved, deferred, createPromise; | ||
end: function (win, fail) { | ||
(win != null) && assertCallable(win); | ||
(fail != null) && assertCallable(fail); | ||
(win == null) || callable(win); | ||
(fail == null) || callable(fail); | ||
this._base.next('end', arguments); | ||
@@ -42,3 +42,3 @@ }, | ||
return resolve((cb == null) ? this.promise : | ||
(isCallable(cb) ? silent.call(cb, this.value) : cb)); | ||
(isCallable(cb) ? silent.call(cb)(this.value) : cb)); | ||
}, | ||
@@ -72,3 +72,3 @@ end: function (win, fail) { | ||
var previous, base; | ||
base = dscr.v(this); | ||
base = dscr('', this); | ||
previous = promise._base; | ||
@@ -98,3 +98,3 @@ this.promise = promise; | ||
this.timeout = setTimeout(noop, 1e13); | ||
this.monitor = deferred.MONITOR && deferred.MONITOR(); | ||
this.monitor = createPromise.monitor && createPromise.monitor(); | ||
}; | ||
@@ -105,3 +105,3 @@ Unresolved.prototype = { | ||
var previous, base; | ||
base = dscr.c(this); | ||
base = dscr('c', this); | ||
if ((previous = promise._base)) { | ||
@@ -108,0 +108,0 @@ clearTimeout(previous.timeout); |
{ | ||
"name": "deferred", | ||
"version": "0.5.3", | ||
"version": "0.5.4", | ||
"description": "Asynchronous control-flow with deferred and promises", | ||
@@ -27,10 +27,9 @@ "keywords": [ | ||
"engines": { | ||
"node": ">=0.1.103" | ||
"node": ">=0.4" | ||
}, | ||
"dependencies": { | ||
"es5-ext": "0.7.x" | ||
"es5-ext": "0.8.x" | ||
}, | ||
"scripts": { | ||
"test": "node ./node_modules/tad/bin/tad lib", | ||
"lint": "node ./node_modules/jslint/bin/jslint.js --color --git" | ||
"test": "node ./node_modules/tad/bin/tad lib" | ||
}, | ||
@@ -37,0 +36,0 @@ "devDependencies": { |
@@ -31,3 +31,3 @@ # Asynchronous JavaScript with deferred and promises | ||
// Filter *.js files | ||
// Filter *.js files and generated lib.js | ||
files = files.filter(function (file) { | ||
@@ -42,3 +42,3 @@ return (file.slice(-3) === '.js') && (file !== 'lib.js'); | ||
++waiting; | ||
readFile(file, 'utf8', function (err, content) { | ||
readFile(file, function (err, content) { | ||
if (err) { | ||
@@ -68,9 +68,9 @@ // We were not able to read file content, throw error | ||
```javascript | ||
var deferred = require('deferred') | ||
var promisify = require('deferred').promisify | ||
, fs = require('fs') | ||
// We prepare promisified versions of each asynchronous function | ||
, readdir = deferred.promisify(fs.readdir) | ||
, readFile = deferred.promisify(fs.readFile) | ||
, writeFile = deferred.promisify(fs.writeFile); | ||
, readdir = promisify(fs.readdir) | ||
, readFile = promisify(fs.readFile) | ||
, writeFile = promisify(fs.writeFile); | ||
@@ -81,3 +81,3 @@ writeFile(__dirname + '/lib.js', | ||
// Filter *.js files | ||
// Filter *.js files and generated lib.js | ||
.invoke('filter', function (file) { | ||
@@ -88,5 +88,3 @@ return (file.slice(-3) === '.js') && (file !== 'lib.js'); | ||
// Read content of all files | ||
.map(function (file) { | ||
return readFile(file, 'utf-8'); | ||
}) | ||
.map(readFile) | ||
@@ -115,2 +113,3 @@ // Concatenate files content into one string | ||
* [Reduce](#collections-reduce) | ||
* [Limitting concurrency](#limitting-concurrency) | ||
* [Promise extensions](#extensions) | ||
@@ -406,13 +405,4 @@ * [cb](#extensions-cb) | ||
There are cases when we don't want to run too many tasks simultaneously. Like common case in Node.js when we don't want to open too many file descriptors. `deferred.map` accepts fourth argument which is maximum number of tasks that should be run at once: | ||
See [limitting concurrency](#limitting-concurrency) section for info on how to limit maximum number of concurrent calls in `map` | ||
```javascript | ||
// Open maximum 100 file descriptors at once | ||
deferred.map(filenames, function (filename) { | ||
return readFile(filename, 'utf-8'); | ||
}, null, 100)(function (result) { | ||
// result is an array of file's contents | ||
}); | ||
``` | ||
<a name="collections-reduce" /> | ||
@@ -434,2 +424,34 @@ ### Reduce | ||
<a name="limitting-concurrency" /> | ||
## Limitting concurrency | ||
There are cases when we don't want to run too many tasks simultaneously. Like common case in Node.js when we don't want to open too many file descriptors. `deferred.map` accepts fourth argument which is maximum number of tasks that should be run at once: | ||
```javascript | ||
// Open maximum 100 file descriptors at once | ||
deferred.map(filenames, function (filename) { | ||
return readFile(filename, 'utf-8'); | ||
}, null, 100)(function (result) { | ||
// result is an array of file's contents | ||
}); | ||
``` | ||
Aside of `deferred.map` there's more generic `deferred.gate` for limitting concurrent calls of same asynchronouns task: | ||
```javascript | ||
var fn = deferred.gate(function async() { | ||
var defer = defered(); | ||
// .. | ||
return defer.promise; | ||
}, 10); | ||
``` | ||
If there's already 10 concurrent task running `async` function invocation will be postponed into the queue and released when some of the running tasks will finish its job. | ||
Additionally we may limit number of postponed calls, so if there's more than _n_ of them rest is discarred, it can be done with third argument. In below example, queue holds maximum 3 postponed calls, rest will be discarded. | ||
```javascript | ||
var fn = deferred.gate(function async() { .. }, 10, 3); | ||
``` | ||
<a name="extensions" /> | ||
@@ -436,0 +458,0 @@ ## Promise extensions |
'use strict'; | ||
var toArray = require('es5-ext/lib/Object/prototype/to-array') | ||
var toArray = require('es5-ext/lib/Array/from') | ||
, isPromise = require('../lib/is-promise'); | ||
@@ -30,3 +30,3 @@ | ||
def = t('$test:back', null, function (args, resolve) { | ||
a.deep(toArray.call(args), [x, y], "Back: args"); | ||
a.deep(toArray(args), [x, y], "Back: args"); | ||
return resolve(v); | ||
@@ -33,0 +33,0 @@ }); |
@@ -8,3 +8,2 @@ 'use strict'; | ||
, contains = require('es5-ext/lib/Array/prototype/contains') | ||
, merge = require('es5-ext/lib/Object/prototype/merge') | ||
, convert = require('es5-ext/lib/String/prototype/dash-to-camel-case') | ||
@@ -23,3 +22,3 @@ , indexTest = require('tad/lib/utils/index-test') | ||
return o; | ||
}), ['delay', 'promisify', 'promisifySync', 'map', | ||
}), ['delay', 'gate', 'promisify', 'promisifySync', 'map', | ||
'reduce']), | ||
@@ -38,2 +37,18 @@ "isPromise": function (t, a) { | ||
}, | ||
"Gate": function (t, a) { | ||
var fn, dx, dy, ready; | ||
fn = t.gate(function (p) { | ||
return p; | ||
}, 1) | ||
dx = t(); | ||
fn(dx.promise); | ||
dy = t(); | ||
fn(dy.promise).end(function (err, r) { | ||
a(ready, true); | ||
}); | ||
dy.resolve({}); | ||
ready = true; | ||
dx.resolve({}); | ||
ready = false; | ||
}, | ||
"Promisify": function (t, a, d) { | ||
@@ -40,0 +55,0 @@ var x = {}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
85447
54
2227
540
+ Addedes5-ext@0.8.2(transitive)
- Removedes5-ext@0.7.1(transitive)
Updatedes5-ext@0.8.x