pax_global_header 0000666 0000000 0000000 00000000064 13500662733 0014517 g ustar 00root root 0000000 0000000 52 comment=03c18097481b1796997626e6315a6a22489fb8a7
deferred-0.7.11/ 0000775 0000000 0000000 00000000000 13500662733 0013365 5 ustar 00root root 0000000 0000000 deferred-0.7.11/.editorconfig 0000664 0000000 0000000 00000000407 13500662733 0016043 0 ustar 00root root 0000000 0000000 # EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
trim_trailing_whitespace = true
[{*.md,*.yml}]
indent_size = 2
indent_style = space
deferred-0.7.11/.github/ 0000775 0000000 0000000 00000000000 13500662733 0014725 5 ustar 00root root 0000000 0000000 deferred-0.7.11/.github/FUNDING.yml 0000664 0000000 0000000 00000000031 13500662733 0016534 0 ustar 00root root 0000000 0000000 tidelift: "npm/deferred"
deferred-0.7.11/.gitignore 0000664 0000000 0000000 00000000041 13500662733 0015350 0 ustar 00root root 0000000 0000000 /node_modules
/package-lock.json
deferred-0.7.11/.testignore 0000664 0000000 0000000 00000000025 13500662733 0015546 0 ustar 00root root 0000000 0000000 /benchmark
/examples
deferred-0.7.11/CHANGELOG.md 0000664 0000000 0000000 00000002300 13500662733 0015171 0 ustar 00root root 0000000 0000000 # Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.7.11](https://github.com/medikoo/deferred/compare/v0.7.10...v0.7.11) (2019-06-14)
## [0.7.10](https://github.com/medikoo/deferred/compare/v0.7.9...v0.7.10) (2018-12-27)
### Bug Fixes
- promise.map on pending then rejected ([e7cfc02](https://github.com/medikoo/deferred/commit/e7cfc02))
## [0.7.9](https://github.com/medikoo/deferred/compare/v0.7.8...v0.7.9) (2017-12-13)
### Features
- `timeout` promise extension ([cbdc9fd](https://github.com/medikoo/deferred/commit/cbdc9fd))
## [0.7.8](https://github.com/medikoo/deferred/compare/v0.7.7...v0.7.8) (2017-05-25)
### Bug Fixes
- **gate:** resolution of rejected promise ([f6fe524](https://github.com/medikoo/deferred/commit/f6fe524))
## [0.7.7](https://github.com/medikoo/deferred/compare/v0.7.6...v0.7.7) (2017-05-24)
### Features
- improve gate error format ([ad4d71b](https://github.com/medikoo/deferred/commit/ad4d71b))
## Old Changelog
Can be found at `CHANGES`
deferred-0.7.11/CHANGES 0000664 0000000 0000000 00000027504 13500662733 0014370 0 ustar 00root root 0000000 0000000 New changes are described in CHANGELOG.md
v0.7.6 -- 2017.03.15
* Fix errors in documentation
* Prevent stack trace related range errors
v0.7.5 -- 2016.01.28
* Fix few stack trace overflow vulnerabilities
* Improve delay arguments handling. `timeout` is now optional
if not provided then `nextTick` is used
otherwise proper validation of input value takes place.
v0.7.4 -- 2015.11.18
* `every` extension
* `dynamicQueue` util
v0.7.3 -- 2015.09.10
* `find` extension (Array's find for promises)
* Fix spelling of LICENSE
v0.7.2 -- 2015.01.07
* Force assimilation of pre v0.7 deferred promises.
Using them as own raised serious bugs
* Configure lint scripts in package.json
v0.7.1 -- 2014.04.27
* Update internals to use latest versions of dependencies
v0.7.0 -- 2014.04.04
Major (breaking) changes:
* Fix error handling:
Up to v0.6.x promise could have been rejected only with error instance, and
same way they couldn't be successfully resolved with an error instance. It was
not an issue if we followed good practices, still it didn't match `throw`
behavior (any JavaScript value can be thrown). Starting from v0.7 promise can
be rejected and resolved with any kind of value. It's also how promises behave
in other implementations including upcoming ECMAScript 6 standard.
* Assimilate foreign promises. Promises from other implemantations (including
native promises) are detected and assimilated for recursive resolution.
Addresses issue #29
* Rename `promise.match` to `promise.spread`, this is the name under which this
functionality was popularized in other libraries.
* Remove `end`, as it was replaced by `done` in v0.6.4 (`end` was kept as an
alias to not break current programs)
* Move modules from `lib` to root folder
Other changes:
* Expose `resolve` and `reject` functions on deferred. It complies to
`Promise.resolve` and `Promise.reject`
* Remove Makefile (it's cross-environment package)
* Fix handling of promise arguments in promisifySync
v0.6.8 -- 2013.12.27
* Function version of `invokeAsync` utility (further addresses #26)
v0.6.7 -- 2013.12.27
* `callAsync` utility, to promisify asynchronous functions inline in algorithm.
Fixes #26
v0.6.6 -- 2013.10.14
* Fix stack overflow vulnerability in `reduce` implementation, as diagnosed
here: https://github.com/cujojs/promise-perf-tests/blob
/e58b90c2660914411c96efe854446444160b592a/lib/tests/reduce-large.js#L25
* Introduce `examples` directory. First examples introduced by
Marc-Aurèle DARCHE (@madarche). Thanks!
* Improve benchmarks, and add kew and bluebird to them (and remove jQuery)
* Documentation: Fix profiler example and general improvements
v0.6.5 -- 2013.06.05
* `catch` extension
* Unify listeners handling in promises handled by gate
* Improve documentation
v0.6.4 -- 2013.05.15
* Rename `done` to `end` and leave `end` as an alias for `done`.
With v0.7 release `end` alias will be removed.
v0.6.3 -- 2013.03.21
* promise.finally extension
v0.6.2 -- 2013.03.18
* Provide deferred.reject to allow configuration of v0.7 safe working flows
* Do not require whole event-emitter but just needed modules
v0.6.1 -- 2012.10.05
* Fix profiler paths detection to work on Windows systems
* Fix monitor test so it's not dependent on order in which is run
* Added When implementation to benchmarks
v0.6.0 -- 2012.09.22
Major refactor, with focus on performance and better modularization.
* New Deferred is about x3 faster than v0.5 version
* Promise is now also an event emitter
* Better extensions system (deferred.extend)
* `aside` extension (derived from `cb`), that allows to split promise chain
* New `cb` extension with different semantics, allows escaping promise chain
with typical asynchronous function callback
* Refactored Array#map, it doesn't support any more limit argument (it should be
now achieved with help of deferred.gate)
* Refactored Array#reduce, added support for sparse arrays
* Array#some - added support for sparse arrays
* Changed signature of `end` it's now on pair with `then` and newly introduced
`aside` extension
* Profiler - gather promise initialization statistics
* Removed promise.js module, some of it's logic is left as internal _ext.js
module and other part was merged into deferred.js
* Benchmarks
v0.5.6 -- 2012-07.17
(Maintenance, as v0.6 is nearly ready for rollout).
Added workaround for for v8 bug (eminent in Node v0.6):
Defining property via descriptor on plain function, prevents us from
setting same property directly later on different function.
v0.5.5 -- 2012.06.13
* deferred.some - (array & promise extension). Promise aware Array's some for
array-like objects.
* Fix handling of callbacks in `cb` promise extension. Only success callback
mode was not handled correctly.
* Mark functions that returns promises with 'returnsPromise' flag, and provide
awareness of that in `promisify` extensions, so they return same functions
back if they're called on such.
* Files reorganization so internal modules are no longer in utils folder but
instead are prefixed with '_' (it's convention we use in other projects)
v0.5.4 -- 2012.05.28
* deferred.gate - (function extension) Handles maximum concurrency number for
given asynchronous task. Additionally postponed calls queue length can also be
limited to chosen number
* Modify code so we can use es5-ext at it's latest version
v0.5.3 -- 2012.05.04
* Fixed resolution of synchronous calls in a queue of map extension, they were
not resolved as expected
v0.5.2 -- 2012.05.02
* Fixed serious issue in `get` extension, which in some scenarios made errors in
following resolved flow silent
v0.5.1 -- 2012.04.29
* Fixed error handling in invoke extension for case in which context object is
null or undefined
v0.5.0 -- 2012.04.18
* Addons & Improvements
* Resigned from dual async/sync: `invoke` extension and `promisify` method.
Such abstraction lead to unexpected results in some cases.
`invokeSync` is from now on `invoke` (`invokeSync` is no longer available),
`promisifyAsync` is now `promisify` (`promisifyAsync` is no longer
available).
* Brought back `cb` extension in slightly different form. It's useful for
creating "hybrid" asynchronous functions that both take callback and return
promise, it can also be useful if we want to split promise chain, return
promise and carry on with other flow.
* `get` now accepts more than one argument, this way we can with one call get
to nested properties of object
* `extend` functions that helps in configuration of promise extensions now
accepts array of validation functions that should be called on extension
initial call.
* Input arguments of promise extensions are now validated on initial call.
It is quite important as error now can be easily tracked down, if we
propagate our error to some next event loop it's more problematic.
* Fixes
* Arguments validation in `extend` function was broken
* When run on resolved promises, errors invoked by some extensions where not
propagated into promise chain as expected
v0.4.3 -- 2012.02.20
* Improvements:
* Added support for fourth argument in deferred.map through which we can set
maximum number of tasks that should be run simultaneously
* Exposed `promisifyAsync` and `promisifySync` on deferred, and exposed by
default `invokeSync` and `invokeAsync` promise extensions
* Added possibility to add just onsuccess callback to `end`
* Optimize internal logic by reducing number of created unresolved promises
* Code validation with JSLint
* Fixes:
* Removed invalid doubled call from invoke extensions
* Handle exceptions thrown by asynchronous functions
v0.4.2 -- 2012.01.26
* Optimization. Cut down promise creation time about 60%
v0.4.1 -- 2012.01.26
* Fixed logic error for multi argument `deferred` call. It was same case as with
`map` fixed with v0.4.0: In specific cases resolve was called in callback
passed to promise, cause of that any errors that occurred in same event loop
were silent.
v0.4.0 -- 2012.01.19
* Changed the way `end` behaves:
* When called without arguments, throws error if promise is rejected
* When called with one function argument, it's treated as callback passed to
Node.js style asynchronous function. When promise is resolved it is called
with two arguments, first is error if promise is rejected, second is
resolved value if promise succeeds.
* When called with two function arguments, first one is taken as onsuccess and
second as onerror (it behaves similar as `then` but it doesn't extend chain
with another promise)
* It no longer returns its promise
* Fixed `map` extension. There was logic error: in specific cases resolve of map
was called in callback passed to promise, cause of that any errors that
occurred in same event loop were silent.
* Removed `cb` extension as now `end` has same functionality
v0.3.1 -- 2012.01.13
* Promisify and invoke extension now resolves also input arguments before
calling the function
* Possibility to preset fixed number of arguments for promisified function,
it makes promisified functions less error prone
v0.3.0 -- 2012.01.08
Major update:
* Revised promise collections approach:
There's no longer all, join & first functions.
Instead we may use deferred for grouping promises: deferred(p1, p2, p3)
or use map or reduce extensions e.g. deferred.map(paths, readFile). See
documentation for more info
* Introduced promise extensions.
* cb - end promise chain with regular asynchronous callback
* get - get property of resolved object
* invoke - invoke function on resolved object (supports both synchronous and
asynchronous functions)
* map - promise aware version of Array's map
* match - match result array to function arguments
* reduce promise aware version of Array's reduce
* Replaced asyncToPromise (used as a2p or ba2p) and syncToPromise (used as s2p
or bs2p) with 'promisify', it works as 'bind' version for both asynchronous
and synchronous functions and is available on deferred as deferred.promisify.
It has also been improved to support asynchronous functions that return more
than one value.
* Rewritten internal logic. Currently promises are backed with _base object
which is different for resolved and unresolved promises
* Removed nextTick rule, no new event loops are introduced by deferred.
* Unresolved promises can now be tracked via deferred.MONITOR
* valueOf promise function. Returns self promise if unresolved and resolved
value if resolved
* isPromise returns true only for deferred's like promise, as deferred api
diverged from other promises implementations it's no open anymore to work
with foreign promises.
* Exposed 'isPromise' & 'delay' functions on deferred
v0.2.6 -- 2011.12.12
* Cleared npm warning for misnamed property in package.json
v0.2.5 -- 2011.11.08
* Fix for bug introduced with node.js >= 0.5.7 ( https://github.com/joyent/node/issues/1877 )
v0.2.4 -- 2011.08.09
* Expose 'promise' function on deferred object returned by index.js.
There are valid use cases for using it outside of deferred lib
v0.2.3 -- 2011.08.09
* 'delay' function: delay execution of given function,
return promise for function result
v0.2.2 -- 2011.08.08
* Added TAD test suite to devDependencies, configured test commands.
Tests can be run with 'make test' or 'npm test'
v0.2.1 -- 2011.08.08
* Use process.nextTick instead of setTimeout if available
v0.2.0 -- 2011.08.08
* Renamed 'chain' dir into 'join' as it's more about joining promises
* promise is now promise.then function (promise === promise.then)
* resolve returns promise, handful for quick function returns
(return d.resolve(x))
* syncToPromise function
* Compatibility with es5-ext v0.6
* Test with TAD
v0.1.2 -- 2011.07.11
* Make it possible to use it with older JavaScript implementations
* Removed dead code
* Better tests coverage
v0.1.1 -- 2011.07.07
* Documentation
v0.1.0 -- 2011.07.05
* Initial version
deferred-0.7.11/LICENSE 0000664 0000000 0000000 00000001405 13500662733 0014372 0 ustar 00root root 0000000 0000000 ISC License
Copyright (c) 2011-2019, Mariusz Nowak, @medikoo, medikoo.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
deferred-0.7.11/README.md 0000664 0000000 0000000 00000065635 13500662733 0014663 0 ustar 00root root 0000000 0000000 [![Build status][semaphore-image]][semaphore-url]
[![Windows status][appveyor-image]][appveyor-url]
[![Transpilation status][transpilation-image]
[![npm version][npm-image]][npm-url]
# Deferred
## Modular and fast Promises implementation for JavaScript
_Implementation originally inspired by Kris Kowal's [Q](https://github.com/kriskowal/q)_
Deferred is complete, [one of the fastest](#performance) and natural promise implementation in JavaScript, with Deferred you can write [clear maintainable code](#promises-approach) that takes maximum out of asynchronicity, in fact due to multi-dimensional nature of promises ([chaining](#chaining) and [nesting](#nesting)) you're forced to program declaratively.
With Deferred you also can: [Process collections](#processing-collections) of deferred calls. [Handle Node.js asynchronous functions](#working-with-asynchronous-functions). [Limit concurrency](#limiting-concurrency) of scheduled tasks. [Emit progress events](#progress-and-other-events) or [stream results partially](#streaming-data-partially) on the go.
In the end you may debug your flow by [tracking unresolved promises](#monitoring-unresolved-promises) or gathering [usage statistics](#usage-statistics).
_For good insight into promise/deferred concept and in general asynchronous programming see also slides from meetjs summit presentation: [Asynchronous JavaScript](http://www.medikoo.com/asynchronous-javascript/)_
**If you need help with deferred, please ask on dedicated mailing list: [deferred-js@googlegroups.com](https://groups.google.com/forum/#!forum/deferred-js)**
### Comparision with callback style
Example of JavaScript files concatenation:
#### Plain Node.js, callbacks approach
```javascript
var fs = require("fs");
var readdir = fs.readdir;
var readFile = fs.readFile;
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;
}
});
}
});
});
});
```
#### Implementation with promises:
```javascript
var promisify = require("deferred").promisify;
var fs = require("fs");
// Convert node.js async functions, into ones that return a promise
var readdir = promisify(fs.readdir);
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)
// 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)
// Concatenate files content into one string
.invoke("join", "\n")
).done(); // If there was any error on the way throw it
```
### Examples
See [examples folder](examples) for a demonstration of promises usage in some other real world cases.
### Installation
#### NPM
In your project path:
\$ npm install deferred
#### Browser
Browser bundle can be easily created with help of [modules-webmake](https://github.com/medikoo/modules-webmake). Assuming that you have latest [Node.js](http://nodejs.org/) and [Git](http://git-scm.com/) installed, following will work in command shell of any system (Linux/MacOS/Windows):
```
$ npm install -g webmake
$ git clone git://github.com/medikoo/deferred.git
$ cd deferred
$ npm install
$ cd ..
$ webmake --name=deferred deferred/index.js deferred.js
```
Last command bundles deferred with all it's functionalities, but you may need just a subset, you can have that by addressing specific modules directly, e.g. with following you will build just core functionality with map extension:
```
$ webmake --name=deferred --include=deferred/ext/promise/map.js deferred/deferred.js deferred.js
```
If you work with AMD modules, use _amd_ option, so generated bundle is one:
```
$ webmake --amd deferred/index.js deferred.js
```
_Mind that deferred relies on some ECMAScript5 features, so for older browsers you need to load as well [es5-shim](https://github.com/kriskowal/es5-shim)_
### Deferred/Promise concept
#### Deferred
For work that doesn't return immediately (asynchronous) you may create deferred object. Deferred holds both `resolve` and `promise` objects. Observers interested in value are attached to `promise` object, with `resolve` we resolve promise with an actual value. In common usage `promise` is returned to the world and `resolve` is kept internally
Let's create `delay` function decorator:
```javascript
var deferred = require('deferred');
var delay = function (fn, timeout) {
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;
}, 100);
var resultPromise = delayedAdd(2, 3);
console.log(deferred.isPromise(resultPromise)); // true
resultPromise(function (value) {
// Invoked after 100 milliseconds
console.log(value); // 5
});
```
#### Promise
Promise is an object that represents eventual value which may already be available or is expected to be available in a future. Promise may succeed (fulfillment) or fail (rejection). Promise can be resolved only once.
In `deferred` (and most of the other promise implementations) you may listen for the value by passing observers to `then` function:
```javascript
promise.then(onsuccess, onfail);
```
In **deferred** promise is really a `then` function, so you may use promise _function_ directly:
```javascript
promise === promise.then; // true
promise(onsuccess, onfail);
```
**If you want to keep clear visible distinction between promises and other object I encourage you to always use `promise.then` notation.**
Both callbacks `onsuccess` and `onfail` are optional. They will be called only once and only either `onsuccess` or `onfail` will be called.
##### Chaining
Promises by nature can be chained. `promise` function returns another promise which is resolved with a value returned by a callback function:
```javascript
delayedAdd(2, 3)(function (result) { return result * result; })(function (result) {
console.log(result); // 25
});
```
It's not just functions that promise function can take, it can be other promises or any other JavaScript value (with exception of `null` or `undefined` which will be treated as no value). Going that way you may override result of a promise chain with specific value.
##### Nesting
Promises can be nested. If a promise resolves with another promise, it's not really resolved. It's resolved only when final promise is resolved with a real value:
```javascript
var def = deferred();
def.resolve(delayedAdd(2, 3)); // Resolve promise with another promise
def.promise(function (result) {
console.log(result); // 5;
});
```
##### Error handling
Errors in promises are handled with separate control flow, that's one of the reasons why code written with promises is more readable and maintainable than when using callbacks approach.
A promise resolved with an error (rejected), propagates its error to all promises that depend on this promise (e.g. promises initiated by adding observers).
If observer function crashes with error or returns error, its promise is rejected with the error.
To handle error, pass dedicated callback as second argument to promise function:
```javascript
delayedAdd(2, 3)(function (result) { throw new Error("Error!"); })(
function () {
// never called
},
function (e) {
// handle error;
}
);
```
##### Ending chain
To expose the errors that are not handled, end promise chain with `.done()`, then error that broke the chain will be thrown:
```javascript
delayedAdd(2, 3)(function (result) { throw new Error("Error!"); })(function (result) {
// never executed
}).done(); // throws error!
```
**It's important to end your promise chains with `done` otherwise eventual ignored errors will not be exposed**.
Signature of `done` function is same as for `then` (or promise itself)
`done` is aliased with `end` function, however `end` will be removed with introduction of v0.7 release.
```javascript
promise(function (value) {
// process
}).done(
function (result) {
// process result
},
function (err) {
// handle error
}
);
```
And as with `then` either callback can be provided. If callback for error was omitted, eventual error will be thrown.
##### Creating resolved promises
You may create initially resolved promises.
```javascript
var promise = deferred(1);
promise(function (result) {
console.log(result); // 1;
});
```
### Working with asynchronous functions
#### promisify(fn[, length])
There is a known convention (coined by Node.js) for working with asynchronous calls. An asynchronous function receives a callback argument which handles both eventual error and expected value:
```javascript
var fs = require("fs");
fs.readFile(__filename, "utf-8", function (err, content) {
if (err) {
// handle error;
return;
}
// process content
});
```
It's not convenient to work with both promises and callback style functions. When you decide to build your flow with promises **don't mix both concepts, just `promisify` asynchronous functions so they return promises instead**.
```javascript
var deferred = require("deferred")
, fs = require("fs")
, readFile = deferred.promisify(fs.readFile);
readFile(__filename, "utf-8")(
function (content) {
// process content
},
function (err) {
// handle error
}
);
```
`promisify` accepts also second argument, through which we may specify length of arguments that function takes (not counting callback argument), it may be handy if there's a chance that unexpected arguments will be passed to function (e.g. Array's `forEach` or `map`)
`promisify` also takes care of input arguments. **It makes sure that all arguments that are to be passed to asynchronous function are first resolved.**
#### callAsync(fn, context, ...args)
If for some reason you need to turn asynchronous functions into ones that return promises, inline in algorithm, then `callAsync` is for you.
Still mind that `promisify` is much better (cleaner) choice if it's possible to prepare reusable wrapper upfront.
```javascript
var callAsync = require("deferred").callAsync;
callAsync(someAsyncFn, context, arg1, arg2).done(function (result) {
// process result
});
```
#### invokeAsync(obj, fnName | fn, ...args)
If you need to turn asynchronous methods to ones that return promises, and you prefer not to augment its class prototypes, `invokeAsync` addresses that use case.
```javascript
var invokeAsync = require("deferred").invokeAsync;
invokeAsync(db, "find", "books", { title: "Some title" }).done(function (book) {
// process result
});
```
## Grouping promises
When we're interested in results of more than one promise object we may group them into one promise with `deferred` function:
```javascript
deferred(delayedAdd(2, 3), delayedAdd(3, 5), delayedAdd(1, 7))(function (result) {
console.log(result); // [5, 8, 8]
});
```
### Processing collections
#### Map
It's analogous to Array's map, with that difference that it returns promise (of an array) that would be resolved when promises for all items are resolved. Any error that would occur will reject the promise and resolve it with same error.
In following example we take content of each file found in an array:
```javascript
var readFile = deferred.promisify(fs.readFile);
deferred.map(filenames, function (filename) { return readFile(filename, "utf-8"); })(function (
result
) {
// result is an array of file's contents
});
```
`map` is also available directly on a promise object, so we may invoke it directly on promise of a collection.
Let's try again previous example but this time instead of relying on already existing filenames, we take list of files from current directory:
```javascript
var readdir = deferred.promisify(fs.readdir);
var readFile = deferred.promisify(fs.readFile);
readdir(__dirname).map(function (filename) { return readFile(filename, "utf-8"); })(function (
result
) {
// result is an array of file's contents
});
```
This function is available also as an extension on promise object.
**See [limiting concurrency](#limiting-concurrency) section for info on how to limit maximum number of concurrent calls in `map`**
#### Reduce
It's same as Array's reduce with that difference that it calls callback only after previous accumulated value is resolved, this way we may accumulate results of collection of promises or invoke some asynchronous tasks one after another.
```javascript
deferred.reduce([delayedAdd(2, 3), delayedAdd(3, 5), delayedAdd(1, 7)], function (a, b) {
return delayedAdd(a, b);
})(function (result) {
console.log(result); // 21
});
```
This function is available also as an extension on promise object.
#### Some
Promise aware Array's some. Process collection one after another and stop when first item matches your criteria
```javascript
deferred.some([filename1, filename2, filename3], function (filename) {
return readFile(filename, "utf8", function (data) {
if (data.indexOf("needle")) {
// Got it! Stop further processing
return true;
}
});
});
```
This function is available also as an extension on promise object.
### Limiting 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.
Handle that with `deferred.gate`, it wraps functions that return promises. It doesn't do anything to promise objects, it just limits creation of them by blocking calls to function it wraps.
```javascript
var fn = deferred.gate(function async() {
var def = deferred();
// ..
return def.promise;
}, 10);
```
If there are already 10 concurrent tasks running `async` function invocation will be postponed into the queue and released when first of the running tasks will finish its job.
Additionally with third argument, we may limit number of postponed calls, so if there's more than _n_ of them rest is discarded. In below example, queue holds maximum 3 postponed calls, rest will be discarded.
```javascript
var fn = deferred.gate(function async() { .. }, 10, 3);
```
In following example we'll limit concurrent readFile calls when using deferred.map:
```javascript
// Open maximum 100 file descriptors at once
deferred.map(
filenames,
deferred.gate(function (filename) { return readFile(filename, "utf-8"); }, 100)
)(function (result) {
// result is an array of file's contents
});
```
### Progress and other events
**Promise objects are also an event emitters**. Deferred implementation is backed by cross-environment [event-emitter solution](https://github.com/medikoo/event-emitter)
Simple Ajax file uploader example:
```javascript
var ajaxFileUploader = function (url, data) {
var def = deferred();
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.onload = def.resolve;
xhr.onerror = function () { def.resolve(new Error("Could not upload files")); };
xhr.upload.onprogress = function (e) { def.promise.emit("progress", e); };
xhr.send(data);
return def.promise;
};
var upload = ajaxFileUploader(formData);
upload.on("progress", function () {
// process progress events
});
upload.done(function (e) {
// All files uploaded!
});
```
#### Streaming data partially
Another use case would be to provide obtained data partially on the go (stream like).
Imagine recursive directory reader that scans whole file system and provides filenames as it approaches them:
```javascript
var reader = readdirDeep(rootPath); // reader promise is returned
reader.on("data", function (someFilenames) {
// Called many times during scan with obtained names
});
reader.done(function (allFilenames) {
// File-system scan finished!
});
```
### Promise extensions
Promise objects are equipped with some useful extensions. All extension are optional but are loaded by default when `deferred` is loaded via `require('deferred')` import.
When preparing client-side file (with help of e.g. [modules-webmake](https://github.com/medikoo/modules-webmake)) you are free to decide, which extensions you want to take (see source of `lib/index.js` on how to do that)
#### aside
Third brother of `then` and `done`. Has same signature but neither extends chain nor ends it, instead splits it by returning promise on which it was invoked. Useful when we want to return promise, but on a side (in parallel) do something else with obtained value:
```javascript
var x = deferred({ foo: "bar" });
var promise = deferred({ foo: "bar" });
var y = promise.aside(function (value) {
console.log(value === x); // true
});
console.log(y === promise); // true
```
#### catch
Same as `then` but accepts only `onFail` callback.
```javascript
var def = deferred(), promise2;
promise2 = def.promise.catch(function () { return "Never mind"; });
def.reject(new Error("Error"));
promise2.done(function (value) {
console.log(value); // Prints "Never mind"
});
```
#### cb
Convert back to callback style. Useful if you want to process regular callback at the end of promise chain. Simple use case would be regular asynchronous function built internally with promises. `cb` also makes sure that your callback is not called immediately but in next tick earliest.
With cb we may build hybrid functions that do both, handle asynchronous callback and return promise:
```javascript
var asyncFunction = function (x, y, callback) {
return someAsyncProcessingThatReturnsPromise(x, y).cb(callback);
});
```
#### finally
Invokes given callback when promise is either fulfilled or rejected
```javascript
var prepare = function () { ... }
, cleanup = function () { ... }
prepare();
promise = asyncFn();
promise.finally(cleanup);
```
#### get
To directly get to object property use `get`
```javascript
var promise = deferred({ foo: "bar" });
promise(function (obj) {
console.log(obj.foo); // 'bar';
});
promise.get("foo")(function (value) {
console.log(value); // 'bar'
});
```
You can get to nested properties as well:
```javascript
var promise = deferred({ foo: { bar: 317 });
promise(function (obj) {
console.log(obj.foo.bar); // 317;
})
promise.get('foo', 'bar')(function (value) {
console.log(value); // 317
});
```
#### invoke & invokeAsync
Schedule function call on returned object
```javascript
var promise = deferred({ foo: function (arg) { return arg * arg; } });
promise.invoke("foo", 3)(function (result) {
console.log(result); // 9
});
// For asynchronous functions use invokeAsync
var promise = deferred({
foo: function (arg, callback) {
setTimeout(function () { callback(null, arg * arg); }, 100);
}
});
promise.invokeAsync("foo", 3)(function (result) {
console.log(result); // 9
});
```
#### map
See [promise aware version of Array's map](#map).
#### reduce
See [promise aware version of Array's reduce](#reduce)
#### some
See [promise aware version of Array's some](#some)
#### spread
If promise expected value is a list that you want to spread into function arguments then use `spread`
```javascript
var promise = deferred([2, 3]);
promise.spread(function (a, b) {
console.log(a + b); // 5
});
```
#### timeout
Resolve with rejection ("Operation timeout" error with `DEFERRED_TIMEOUT` code), if given promise
won't settle with resolved value within given _timeout_
```javascript
var deferred = new Deferred();
deferred.promise.timeout(30).done(function (value) {
console.log("Never called");
}, function () {
console.log("Rejected after 30 seconds");
});
deferred = new Deferred();
deferred.promise.timeout(30).done(function (value) {
console.log("Resolved with", value); // Resolved with true
}, function () {}
console.log("Never called");
});
setTimeout(function () {
deferred.resolve(true);
}, 10);
```
### Debugging
#### Monitoring unresolved promises
In properly constructed flow, there should be no promises that are never resolved.
If you want to be sure that it's not the case, or you suspect there are such issues, check whether deferred's monitor has something to say
```javascript
deferred.monitor();
```
By default monitor will log error for every promise that was not resolved in 5 seconds.
You can customize that timeout, and handle errors with your own listener:
```javascript
deferred.monitor(10000, function (err) {
// Called for each promise not resolved in 10 seconds time
});
```
This extension affects performance and it's best not to use it in production environment
#### Usage statistics
Being able to see how many promises were initialized (and where) in our flow can be helpful to track application issues, it's also good way to confirm that constructed flow works as intended.
```javascript
deferred.profile(); // Start collecting statistics
//...
var stats = deferred.profileEnd(); // End profiling
console.log(stats.log); // See readable output
```
Example log output:
```
------------------------------------------------------------
Deferred/Promise usage statistics:
104540 Total promises initialized
104540 Initialized as Unresolved
0 Initialized as Resolved
Unresolved promises were initialized at:
22590 at Object.module.exports.factory (/Users/medikoo/Projects/_packages/next/lib/fs/_memoize-watcher.js:21:10)
11553 at Object.IsIgnored.init (/Users/medikoo/Projects/_packages/next/lib/fs/is-ignored.js:140:18)
11553 at module.exports.factory (/Users/medikoo/Projects/_packages/next/lib/fs/_memoize-watcher.js:21:10)
7854 at Object.Readdir.filterIgnored (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:434:23)
4619 at Object.module.exports.factory (/Users/medikoo/Projects/_packages/next/lib/fs/_memoize-watcher.js:21:10)
3927 at Object.Readdir.filterByType (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:222:15)
3927 at Object.Readdir.filterByType (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:236:15)
3927 at Object.self (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:164:12)
3927 at Object.Readdir.readdir (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:540:9)
3927 at Object.self (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:164:21)
3729 at directory (/Users/medikoo/Projects/_packages/next/lib/fs/_watch-alt.js:95:2)
2820 at Readdir.filterIgnored.promise.root (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:517:9)
2163 at basic (/Users/medikoo/Projects/_packages/next/lib/fs/is-gitrepo-root.js:14:8)
2159 at buildMap (/Users/medikoo/Projects/_packages/next/lib/fs/is-ignored.js:117:22)
2159 at Object.FindRoot (/Users/medikoo/Projects/_packages/next/lib/fs/find-root.js:18:15)
1107 at Readdir.filterIgnored.promise.root (/Users/medikoo/Projects/_packages/next/lib/fs/readdir.js:527:11)
697 at Object.Map.addPaths (/Users/medikoo/Projects/_packages/next/lib/fs/_get-conf-file-map.js:107:19)
697 at readFile (/Users/medikoo/Projects/_packages/next/lib/fs/read-file.js:18:8)
697 at Object.readRulesWatch (/Users/medikoo/Projects/_packages/next/lib/fs/_get-conf-file-map.js:45:12)
247 at module.exports (/Users/medikoo/Projects/_packages/next/lib/fs/_watch.js:90:2)
247 at module.exports (/Users/medikoo/Projects/_packages/next/lib/fs/_watch.js:90:13)
1 at Object.Readdir.init (/Users/medikoo/Projects/_packa
```
**Using profiler significantly affects performance don't use it in production environment.**
### Performance
Promises just by being rich objects introduce overhead over regular callbacks. If we do a lot asynchronous operations that are fast, performance of promise implementation that we rely on becomes a significant factor.
_benchmark_ folder contains two tests. Tests reflect real use case I had in which performance of promise implementation appeared to be crucial.
Base of a test is [lstat](http://nodejs.org/api/all.html#all_fs_lstat_path_callback) (fastest asynchronous call in node.js API), It's called 10000 times in parallel and sequentially.
_Note for benchmark purists: This test does real I/O, but there's no way to produce shim which will provide more reliable results (shim based on `setImmediate` adds more randomness to result than we got from calling real `lstat`)_
_Example output taken under Node v0.10.20 on 2008 MBP._
```
Promise overhead (calling one after another) x10000:
1: 439ms Base (plain Node.js lstat call)
2: 461ms Kew: Dedicated wrapper
3: 609ms Bluebird: Dedicated wrapper
4: 614ms Bluebird: Promisify (generic wrapper)
5: 642ms Deferred: Dedicated wrapper
6: 720ms Deferred: Promisify (generic wrapper)
7: 792ms When: Dedicated wrapper
8: 1068ms Q: Dedicated wrapper
9: 1611ms Q: nbind (generic wrapper)
Promise overhead (concurrent calls) x10000:
1: 279ms Base (plain Node.js lstat call)
2: 293ms Bluebird: Promisify (generic wrapper)
3: 294ms Bluebird: Dedicated wrapper
4: 329ms Kew: Dedicated wrapper
5: 406ms When: Dedicated wrapper
6: 430ms Deferred: Dedicated wrapper
7: 598ms Deferred: Promisify (generic wrapper)
8: 683ms Deferred: Map + Promisify
9: 1610ms Q: Dedicated wrapper
10: 3645ms Q: nbind (generic wrapper)
```
### Tests
**Covered by over 300 unit tests**
$ npm test
## Security contact information
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
---
[semaphore-image]: https://semaphoreci.com/api/v1/medikoo-org/deferred/branches/master/badge.svg
[semaphore-url]: https://semaphoreci.com/medikoo-org/deferred
[appveyor-image]: https://img.shields.io/appveyor/ci/medikoo/deferred.svg
[appveyor-url]: https://ci.appveyor.com/project/medikoo/deferred
[codecov-image]: https://img.shields.io/codecov/c/github/medikoo/deferred.svg
[codecov-url]: https://codecov.io/gh/medikoo/deferred
[transpilation-image]: https://img.shields.io/badge/transpilation-free-brightgreen.svg
[npm-image]: https://img.shields.io/npm/v/deferred.svg
[npm-url]: https://www.npmjs.com/package/deferred
deferred-0.7.11/_ext.js 0000664 0000000 0000000 00000005656 13500662733 0014676 0 ustar 00root root 0000000 0000000 "use strict";
var callable = require("es5-ext/object/valid-callable")
, isCallable = require("es5-ext/object/is-callable")
, isValue = require("es5-ext/object/is-value")
, d = require("d")
, ee = require("event-emitter")
, isPromise = require("./is-promise");
var create = Object.create, defineProperty = Object.defineProperty, deferred, resolve, reject;
module.exports = exports = function (name, unres, onres, res) {
name = String(name);
callable(res);
if (isValue(onres)) callable(onres);
callable(unres);
defineProperty(exports._unresolved, name, d(unres));
exports._onresolve[name] = onres;
defineProperty(exports._resolved, name, d(res));
exports._names.push(name);
};
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, def.reject]);
return def.promise;
}),
done: d(function (win, fail) {
if (isValue(win)) callable(win);
if (isValue(fail)) callable(fail);
if (!this.pending) this.pending = [];
this.pending.push("done", arguments);
}),
resolved: d(false),
returnsPromise: d(true),
valueOf: d(function () { return this; })
})
);
exports._onresolve = {
then: function (win, fail, promiseResolve, promiseReject) {
var value, cont = this.failed ? fail : win;
if (!isValue(cont)) {
if (this.failed) promiseReject(this.value);
else promiseResolve(this.value);
return;
}
if (isCallable(cont)) {
if (isPromise(cont)) {
if (cont.resolved) {
if (cont.failed) promiseReject(cont.value);
else promiseResolve(cont.value);
return;
}
cont.done(promiseResolve, promiseReject);
return;
}
try {
value = cont(this.value);
} catch (e) {
promiseReject(e);
return;
}
promiseResolve(value);
return;
}
promiseResolve(cont);
},
done: function (win, fail) {
if (this.failed) {
if (fail) {
fail(this.value);
return;
}
throw this.value;
}
if (win) win(this.value);
}
};
exports._resolved = ee(
create(Function.prototype, {
then: d(function (win, fail) {
var value, cont = this.failed ? fail : win;
if (!isValue(cont)) return this;
if (isCallable(cont)) {
if (isPromise(cont)) return cont;
try { value = cont(this.value); }
catch (e) { return reject(e); }
return resolve(value);
}
return resolve(cont);
}),
done: d(function (win, fail) {
if (isValue(win)) callable(win);
if (isValue(fail)) callable(fail);
if (this.failed) {
if (fail) {
fail(this.value);
return;
}
throw this.value;
}
if (win) win(this.value);
}),
resolved: d(true),
returnsPromise: d(true),
valueOf: d(function () { return this.value; })
})
);
deferred = require("./deferred");
resolve = deferred.resolve;
reject = deferred.reject;
deferred.extend = exports;
deferred-0.7.11/appveyor.yml 0000664 0000000 0000000 00000001207 13500662733 0015755 0 ustar 00root root 0000000 0000000 # Test against the latest version of this Node.js version
environment:
matrix:
# node.js
- nodejs_version: "0.12"
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "9"
# Install scripts. (runs after repo cloning)
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
# install modules
- npm install
# Post-install test scripts.
test_script:
# Output useful info for debugging.
- node --version
- npm --version
# run tests
- npm test
# Don't actually build.
build: off
deferred-0.7.11/assimilate.js 0000664 0000000 0000000 00000002320 13500662733 0016053 0 ustar 00root root 0000000 0000000 // 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");
var 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 (resolvedValue) { def.resolve(self(resolvedValue)); };
reject = function (resolvedReason) { def.reject(resolvedReason); };
if (typeof done === "function") {
try { done.call(value, resolve, reject); }
catch (e) { return def.reject(e); }
return def.promise;
}
try {
then.call(
value,
function (resolvedValue) {
nextTick(function () { resolve(resolvedValue); });
},
function (resolvedReason) {
nextTick(function () { reject(resolvedReason); });
}
);
} catch (e) {
return def.reject(e);
}
return def.promise;
};
deferred-0.7.11/benchmark/ 0000775 0000000 0000000 00000000000 13500662733 0015317 5 ustar 00root root 0000000 0000000 deferred-0.7.11/benchmark/.eslintrc.json 0000664 0000000 0000000 00000000076 13500662733 0020116 0 ustar 00root root 0000000 0000000 { "env": { "node": true }, "rules": { "no-console": "off" } }
deferred-0.7.11/benchmark/concurrent.js 0000664 0000000 0000000 00000020734 13500662733 0020045 0 ustar 00root root 0000000 0000000 /* eslint max-lines: "off" */
"use strict";
// Benchmark comparing performance of promise setups (concurrent)
// To run it, do following in package path:
//
// $ npm install Q when kew bluebird
// $ node benchmark/concurrent.js
var generate = require("es5-ext/array/generate")
, forEach = require("es5-ext/object/for-each")
, pad = require("es5-ext/string/#/pad")
, lstat = require("fs").lstat
, QLib = require("Q")
, Bluebird = require("bluebird")
, kew = require("kew")
, when = require("when")
, deferred = require("../");
var now = Date.now
, Deferred = deferred.Deferred
, promisify = deferred.promisify
, nextTick = process.nextTick
, self
, time
, count = 10000
, data = {}
, next
, tests
, def = deferred()
, files = generate(count, __filename);
console.log("Promise overhead (concurrent calls)", "x" + count + ":\n");
// Plain
tests = [
function () {
var i = count, j = count;
self = function () {
lstat(__filename, function (err) {
if (err) throw err;
if (!--i) next(); // Ignore first
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count;
self = function () {
lstat(__filename, function (err) {
if (err) throw err;
if (!--i) {
data["Base (plain Node.js lstat call)"] = now() - time;
next();
}
});
};
time = now();
while (j--) self();
// Bluebird
},
function () {
var i = count, j = count, dlstat = Bluebird.promisify(lstat);
self = function () {
dlstat(__filename).done(function () {
if (!--i) next(); // Ignore first
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat = Bluebird.promisify(lstat);
self = function () {
dlstat(__filename).done(function () {
if (!--i) {
data["Bluebird: Promisify (generic wrapper)"] = now() - time;
next();
}
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
return new Bluebird(function (resolve, reject) {
lstat(path, function (err, stats) {
if (err) reject(err);
else resolve(stats);
});
});
};
self = function () {
dlstat(__filename).done(function () {
if (!--i) next(); // Ignore first
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
return new Bluebird(function (resolve, reject) {
lstat(path, function (err, stats) {
if (err) reject(err);
else resolve(stats);
});
});
};
self = function () {
dlstat(__filename).done(function () {
if (!--i) {
data["Bluebird: Dedicated wrapper"] = now() - time;
next();
}
});
};
time = now();
while (j--) self();
// Kew
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = kew.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef;
};
self = function () {
dlstat(__filename).then(
function () {
if (!--i) nextTick(next); // Ignore first
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = kew.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef;
};
self = function () {
dlstat(__filename).then(
function () {
if (!--i) {
data["Kew: Dedicated wrapper"] = now() - time;
// Get out of try/catch clause
nextTick(next);
}
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
while (j--) self();
// Deferred
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = new Deferred();
lstat(path, function (err, stats) { localDef.resolve(err || stats); });
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function () {
if (!--i) next(); // Ignore first
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = new Deferred();
lstat(path, function (err, stats) { localDef.resolve(err || stats); });
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function () {
if (!--i) {
data["Deferred: Dedicated wrapper"] = now() - time;
next();
}
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat = promisify(lstat);
self = function () {
dlstat(__filename).done(function () {
if (!--i) next(); // Ignore first
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat = promisify(lstat);
self = function () {
dlstat(__filename).done(function () {
if (!--i) {
data["Deferred: Promisify (generic wrapper)"] = now() - time;
next();
}
});
};
time = now();
while (j--) self();
},
function () {
var dlstat = promisify(lstat);
time = now();
deferred.map(files, function (name) { return dlstat(name); }).done(function () { next(); });
},
function () {
var dlstat = promisify(lstat);
time = now();
deferred.map(files, function (name) { return dlstat(name); }).done(function () { next(); });
},
function () {
var dlstat = promisify(lstat);
time = now();
deferred
.map(files, function (name) { return dlstat(name); })
.done(function () {
data["Deferred: Map + Promisify"] = now() - time;
next();
});
// Q
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = QLib.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function () { if (!--i) next(); });
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = QLib.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function () {
if (!--i) {
data["Q: Dedicated wrapper"] = now() - time;
next();
}
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat = QLib.nbind(lstat, null);
self = function () {
dlstat(__filename).done(function () { if (!--i) next(); });
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat = QLib.nbind(lstat, null);
self = function () {
dlstat(__filename).done(function () {
if (!--i) {
data["Q: nbind (generic wrapper)"] = now() - time;
// Get out of try/catch clause
next();
}
});
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = when.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).then(
function () { if (!--i) nextTick(next); },
function (e) {
nextTick(function () { throw e; });
}
);
};
time = now();
while (j--) self();
},
function () {
var i = count, j = count, dlstat;
dlstat = function (path) {
var localDef = when.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).then(
function () {
if (!--i) {
data["When: Dedicated wrapper"] = now() - time;
nextTick(next);
}
},
function (e) {
nextTick(function () { throw e; });
}
);
};
time = now();
while (j--) self();
}
];
next = function () {
setTimeout(function () {
if (tests.length) {
tests.shift()();
} else {
def.resolve();
forEach(
data,
function (value, name, obj, index) {
console.log(
pad.call(index + 1 + ":", " ", 3), pad.call(value, " ", 5) + "ms ", name
);
},
null,
function (data1, data2) { return this[data1] - this[data2]; }
);
}
}, 100);
};
next();
deferred-0.7.11/benchmark/one-after-another.js 0000664 0000000 0000000 00000020654 13500662733 0021202 0 ustar 00root root 0000000 0000000 /* eslint max-lines: "off" */
"use strict";
// Benchmark comparing overhead introduced by promise implementations
// (one by after another)
// To run it, do following in package path:
//
// $ npm install Q when kew bluebird
// $ node benchmark/one-after-another.js
var forEach = require("es5-ext/object/for-each")
, pad = require("es5-ext/string/#/pad")
, lstat = require("fs").lstat
, QLib = require("Q")
, Bluebird = require("bluebird")
, kew = require("kew")
, when = require("when")
, deferred = require("../");
var now = Date.now
, Deferred = deferred.Deferred
, promisify = deferred.promisify
, nextTick = process.nextTick
, self
, time
, count = 10000
, data = {}
, next
, tests
, def = deferred();
console.log("Promise overhead (calling one after another)", "x" + count + ":\n");
// Base
tests = [
function () {
var i = count;
self = function () {
lstat(__filename, function (err, stats) {
if (err) throw err;
if (--i) self(stats);
else next(); // Ignore first one
});
};
time = now();
self();
},
function () {
var i = count;
self = function () {
lstat(__filename, function (err, stats) {
if (err) throw err;
if (--i) {
self(stats);
} else {
data["Base (plain Node.js lstat call)"] = now() - time;
next();
}
});
};
time = now();
self();
// Bluebird
},
function () {
var i = count, dlstat = Bluebird.promisify(lstat);
self = function () {
dlstat(__filename).done(
function (stats) {
if (--i) self(stats);
else next();
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
self();
},
function () {
var i = count, dlstat = Bluebird.promisify(lstat);
self = function () {
dlstat(__filename).done(
function (stats) {
if (--i) {
self(stats);
} else {
data["Bluebird: Promisify (generic wrapper)"] = now() - time;
// Get out of try/catch clause
next();
}
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
self();
},
function () {
var i = count, dlstat;
dlstat = function (path) {
return new Bluebird(function (resolve, reject) {
lstat(path, function (err, stats) {
if (err) reject(err);
else resolve(stats);
});
});
};
self = function () {
dlstat(__filename).done(
function (stats) {
if (--i) self(stats);
else next();
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
self();
},
function () {
var i = count, dlstat;
dlstat = function (path) {
return new Bluebird(function (resolve, reject) {
lstat(path, function (err, stats) {
if (err) reject(err);
else resolve(stats);
});
});
};
self = function () {
dlstat(__filename).done(
function (stats) {
if (--i) {
self(stats);
} else {
data["Bluebird: Dedicated wrapper"] = now() - time;
// Get out of try/catch clause
next();
}
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
self();
// Kew
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = kew.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef;
};
self = function () {
dlstat(__filename).then(
function (stats) {
if (--i) self(stats);
else nextTick(next);
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
self();
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = kew.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef;
};
self = function () {
dlstat(__filename).then(
function (stats) {
if (--i) {
self(stats);
} else {
data["Kew: Dedicated wrapper"] = now() - time;
// Get out of try/catch clause
nextTick(next);
}
},
function (err) {
nextTick(function () { throw err; });
}
);
};
time = now();
self();
// Deferred
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = new Deferred();
lstat(path, function (err, stats) { localDef.resolve(err || stats); });
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) self(stats);
else next(); // Ignore first one
});
};
time = now();
self();
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = new Deferred();
lstat(path, function (err, stats) { localDef.resolve(err || stats); });
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) {
self(stats);
} else {
data["Deferred: Dedicated wrapper"] = now() - time;
next();
}
});
};
time = now();
self();
},
function () {
var i = count, dlstat = promisify(lstat);
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) self(stats);
else next(); // Ignore first one
});
};
time = now();
self();
},
function () {
var i = count, dlstat = promisify(lstat);
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) {
self(stats);
} else {
data["Deferred: Promisify (generic wrapper)"] = now() - time;
next();
}
});
};
time = now();
self();
// Q
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = QLib.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) self(stats);
else next();
});
};
time = now();
self();
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = QLib.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) {
self(stats);
} else {
data["Q: Dedicated wrapper"] = now() - time;
// Get out of try/catch clause
next();
}
});
};
time = now();
self();
},
function () {
var i = count, dlstat = QLib.nbind(lstat, null);
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) self(stats);
else next();
});
};
time = now();
self();
},
function () {
var i = count, dlstat = QLib.nbind(lstat, null);
self = function () {
dlstat(__filename).done(function (stats) {
if (--i) {
self(stats);
} else {
data["Q: nbind (generic wrapper)"] = now() - time;
next();
}
});
};
time = now();
self();
// When
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = when.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).then(
function (stats) {
if (--i) self(stats);
else nextTick(next);
},
function (e) {
nextTick(function () { throw e; });
}
);
};
time = now();
self();
},
function () {
var i = count, dlstat;
dlstat = function (path) {
var localDef = when.defer();
lstat(path, function (err, stats) {
if (err) localDef.reject(err);
else localDef.resolve(stats);
});
return localDef.promise;
};
self = function () {
dlstat(__filename).then(
function (stats) {
if (--i) {
self(stats);
} else {
data["When: Dedicated wrapper"] = now() - time;
nextTick(next);
}
},
function (e) {
nextTick(function () { throw e; });
}
);
};
time = now();
self();
}
];
next = function () {
setTimeout(function () {
if (tests.length) {
tests.shift()();
} else {
def.resolve();
forEach(
data,
function (value, name, obj, index) {
console.log(
pad.call(index + 1 + ":", " ", 3), pad.call(value, " ", 5) + "ms ", name
);
},
null,
function (data1, data2) { return this[data1] - this[data2]; }
);
}
}, 100);
};
next();
deferred-0.7.11/deferred.js 0000664 0000000 0000000 00000013437 13500662733 0015513 0 ustar 00root root 0000000 0000000 /* eslint max-statements: "off", max-depth: "off" */
// Returns function that returns deferred or promise object.
//
// 1. If invoked without arguments then deferred object is returned
// Deferred object consist of promise (unresolved) function and resolve
// function through which we resolve promise
// 2. If invoked with one argument then promise is returned which resolved value
// is given argument. Argument may be any value (even undefined),
// if it's promise then same promise is returned
// 3. If invoked with more than one arguments then promise that resolves with
// array of all resolved arguments is returned.
"use strict";
var isError = require("es5-ext/error/is-error")
, noop = require("es5-ext/function/noop")
, setPrototypeOf = require("es5-ext/object/set-prototype-of")
, isPromise = require("./is-promise");
var every = Array.prototype.every
, push = Array.prototype.push
, getPrototypeOf = Object.getPrototypeOf
, Deferred
, createDeferred
, count = 0
, timeout
, extendShim
, ext
, resolve
, assimilate;
extendShim = function (promise) {
ext._names.forEach(function (name) {
promise[name] = function () {
return getPrototypeOf(promise)[name].apply(promise, arguments);
};
});
promise.returnsPromise = true;
promise.resolved = getPrototypeOf(promise).resolved;
};
resolve = function (value, failed) {
var promise = function (win, fail) { return promise.then(win, fail); };
promise.value = value;
promise.failed = failed;
if (setPrototypeOf) setPrototypeOf(promise, ext._resolved);
else 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);
++count;
if (createDeferred._monitor) promise.monitor = createDeferred._monitor();
if (setPrototypeOf) setPrototypeOf(promise, ext._unresolved);
else extendShim(promise);
if (createDeferred._profile) createDeferred._profile();
this.promise = promise;
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
};
Deferred.prototype = {
resolved: false,
_settle: function (value) {
var i, name, data, deps, dPromise, nuDeps;
this.promise.value = value;
if (setPrototypeOf) setPrototypeOf(this.promise, ext._resolved);
else this.promise.resolved = true;
deps = this.promise.dependencies;
delete this.promise.dependencies;
while (deps) {
for (i = 0; (dPromise = deps[i]); ++i) {
dPromise.value = value;
dPromise.failed = this.failed;
if (setPrototypeOf) setPrototypeOf(dPromise, ext._resolved);
else dPromise.resolved = true;
delete dPromise.pending;
if (dPromise.dependencies) {
if (nuDeps) push.apply(nuDeps, dPromise.dependencies);
else nuDeps = dPromise.dependencies;
delete dPromise.dependencies;
}
}
deps = nuDeps;
nuDeps = null;
}
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) {
value.dependencies = [];
}
value.dependencies.push(this.promise);
if (this.promise.pending) {
if (value.pending) {
this.promise.pending.forEach(function (promise) {
value.pending.push(promise);
});
this.promise.pending = value.pending;
if (this.promise.dependencies) {
this.promise.dependencies.forEach(function self(dPromise) {
dPromise.pending = value.pending;
if (dPromise.dependencies) {
dPromise.dependencies.forEach(self);
}
});
}
} else {
value.pending = this.promise.pending;
}
} else if (value.pending) {
this.promise.pending = value.pending;
} else {
this.promise.pending = value.pending = [];
}
return this.promise;
}
this.promise.failed = value.failed;
value = value.value;
}
return this._settle(value);
},
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 length = arguments.length, d, waiting, initialized, result;
if (!length) return new Deferred();
if (length > 1) {
d = new Deferred();
waiting = 0;
result = new Array(length);
every.call(arguments, function (itemValue, index) {
itemValue = assimilate(itemValue);
if (!isPromise(itemValue)) {
result[index] = itemValue;
return true;
}
if (itemValue.resolved) {
if (itemValue.failed) {
d.reject(itemValue.value);
return false;
}
result[index] = itemValue.value;
return true;
}
++waiting;
itemValue.done(function (resolvedValue) {
result[index] = resolvedValue;
if (!--waiting && initialized) d.resolve(result);
}, d.reject);
return true;
});
initialized = true;
if (!waiting) d.resolve(result);
return d.promise;
}
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");
deferred-0.7.11/dynamic-queue.js 0000664 0000000 0000000 00000002717 13500662733 0016500 0 ustar 00root root 0000000 0000000 // Dynamic queue handler
// Allows to create a promise queue, where new promises can be added to queue until last promise in
// a queue resolves. Queue promise resolves with `undefined` value, when last promises resolves.
"use strict";
var aFrom = require("es5-ext/array/from")
, ensureIterable = require("es5-ext/iterable/validate-object")
, assign = require("es5-ext/object/assign")
, deferred = require("./deferred")
, isPromise = require("./is-promise")
, assimilate = require("./assimilate");
var DynamicQueue;
module.exports = DynamicQueue = function (list) {
if (!(this instanceof DynamicQueue)) return new DynamicQueue(list);
list = aFrom(ensureIterable(list));
assign(this, deferred());
list.every(this.add, this);
if (!this.waiting) {
this.resolve();
return null;
}
this.initialized = true;
return null;
};
DynamicQueue.prototype = {
waiting: 0,
initialized: false,
add: function (value) {
if (this.promise.resolved) throw new Error("Queue was already resolved");
++this.waiting;
value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
value.done(this._processValue.bind(this), this.reject);
return true;
}
if (value.failed) {
this.reject(value.value);
return false;
}
}
return this._processValue();
},
_processValue: function () {
if (this.promise.resolved) return null;
if (!--this.waiting && this.initialized) this.resolve();
return true;
}
};
deferred-0.7.11/examples/ 0000775 0000000 0000000 00000000000 13500662733 0015203 5 ustar 00root root 0000000 0000000 deferred-0.7.11/examples/.eslintrc.json 0000664 0000000 0000000 00000000127 13500662733 0017777 0 ustar 00root root 0000000 0000000 { "rules": { "no-console": "off", "no-unused-vars": "off" }, "env": { "node": true } }
deferred-0.7.11/examples/gather-paginated-search-results.js 0000664 0000000 0000000 00000002150 13500662733 0023705 0 ustar 00root root 0000000 0000000 "use strict";
// Let's say we're after content that is paginated over many pages on some
// website (like search results). We don't know how many pages it spans.
// We only know by reading page n whether page n + 1 exists.
// 1. Define simple download function, it downloads page at given path from
// predefinied domain and returns promise:
var deferred = require("deferred")
, http = require("http");
var getPage, pageN, result = {};
getPage = function (path) {
var d = deferred();
http.get({ host: "www.example.com", path: path }, function (res) {
res.setEncoding("utf-8");
var content = "";
res.on("data", function (data) { content += data; });
res.on("end", function () { d.resolve(content); });
}).on("error", d.reject);
return d.promise;
};
// 2. Invoke promise loop
pageN = 1;
getPage("/page/" + pageN)(function processContent(content) {
var isNextPage = false;
// ...populate result...
// ...decide whether we need to download next page
if (isNextPage) return getPage("/page/" + ++pageN)(processContent);
return result;
}).done(function (finalResult) {
// Process final result
});
deferred-0.7.11/examples/process-directory-of-html-files.js 0000664 0000000 0000000 00000007544 13500662733 0023677 0 ustar 00root root 0000000 0000000 "use strict";
// Read meta data out of each html file in given directory.
// Requires jsdom package installed:
//
// $ npm install jsdom
//
// and folder with some html files
//
// Usage:
//
// var extract = require('deferred/examples/process-directory-of-html-files');
// extract('/some/path/to/html/files').done(function (result) {
// console.log("Result:", result);
// });
var fs = require("fs")
, path = require("path")
, jsdom = require("jsdom")
, deferred = require("deferred");
// Convert Node.js async functions, into ones that return a promise
var promisify = deferred.promisify
, readdir = promisify(fs.readdir)
, open = promisify(fs.open)
, read = promisify(fs.read)
, close = promisify(fs.close)
, stat = promisify(fs.stat)
, extract
, readFirstBytes;
extract = function (html) {
var def = deferred(), data = this;
// Process HTML with jsdom parser
jsdom.env({
html: String(html),
done: function (errors, window) {
var elems;
if (errors) {
def.reject(new Error(errors));
return;
}
// The title is the content of the 1st "h1" element
elems = window.document.getElementsByTagName("h1");
if (elems.length) data.title = elems[0].textContent;
// The description is the content of the 1st "p" element
elems = window.document.getElementsByTagName("p");
if (elems.length) data.description = elems[0].textContent;
def.resolve(data);
}
});
return def.promise;
};
readFirstBytes = function (filePath, byteCount) {
return open(filePath, "r").then(function (fd) {
var buffer = Buffer.alloc(byteCount);
return read(fd, buffer, 0, buffer.length, null).then(
// The callback of fs.read has 2 args: bytesRead, buffer
function (args) {
close(fd);
return String(args[1]);
}
);
});
};
module.exports = function (rootPath) {
var result = {};
// Read folder
//
// Note: If you are about to process large numbers of files, on some systems
// you may approach EMFILE error, which means that your process tried to open
// more file descriptors than it's allowed to. You can workaround it in two
// ways:
// 1. Load `descriptorsHandler` from fs2 package
// (see https://github.com/medikoo/fs2#descriptorshandler ),
// note it must not be loaded from generic package, but only at the top of
// your start program.
//
// 2. Limit initialization of concurrent asynchronous operations with
// `deferred.gate`:
//
// readdir(root).map(deferred.gate(function (fileName) { ... }, 100);
//
// Above will invoke no more than 100 concurrent async calls of `readFile`
// as they're called in function passed to `gate`
return readdir(rootPath).map(function (fileName) {
// Process only HTML files
if (path.extname(fileName) !== ".html") return null;
// Note: You may also use `readdir` from `fs2` package (needs to be
// installed aside), then you can configure `readdir` so it results only
// with expected set of filenames and additionally you can recurse into sub
// directories:
//
// var readdir = require('fs2/readdir');
//
// readdir(root, {
// depth: Infinity // Recurse into subdirectories
// type: { file: true } // Only files (no directories, symlinks etc)
// pattern: /.*\.html$/ // Only files with .html extension
// }).map(function (fileName) {
//
// `readdir` from fs2 returns promise by itself, so it doesn't have to be
// promisified
// Resolve full path to file
fileName = path.resolve(rootPath, fileName);
// Read file stats
return stat(fileName).then(function (stats) {
var data = { stats: stats, fileName: fileName };
result[fileName] = data;
// We read just first 12k bytes, but you can also parse whole HTML
// document with following:
//
// var readFile = promisify(fs.readFile);
// return readFile(fileName);
return readFirstBytes(fileName, 12000).then(extract.bind(data));
});
})(result);
};
deferred-0.7.11/examples/test-with-mocha-and-should.js 0000664 0000000 0000000 00000002571 13500662733 0022617 0 ustar 00root root 0000000 0000000 /* eslint-env mocha */
"use strict";
// Example demonstrating the use of deferred in the context of unit tests with
// the mocha and should modules.
//
// Usage:
// $ mocha test/deferred_with_mocha_and_should.test.js
var should = require("should")
, deferred = require("deferred");
describe("Async functions with promises", function () {
it("should produce a result without error", function (done) {
var asyncFunc1, asyncFunc2, asyncFunc3;
asyncFunc1 = function (params) {
console.log("params:", params);
var def = deferred();
// Some async processing
setTimeout(function () { def.resolve(params + "with"); }, 100);
return def.promise;
};
asyncFunc2 = function (params) {
console.log("params:", params);
var def = deferred();
// Some async processing
setTimeout(function () { def.resolve(params + "some"); }, 100);
return def.promise;
};
asyncFunc3 = function (params) {
console.log("params:", params);
var def = deferred();
// Some async processing
setTimeout(function () { def.resolve(params + "more"); }, 100);
return def.promise;
};
asyncFunc1("Intial_value").then(asyncFunc2).then(asyncFunc3).done(
function (result) {
console.log("Final result is:", result);
result.should.equal("Intial_valuewithsomemore");
done();
},
function (err) {
should.not.exist(err);
done();
}
);
});
});
deferred-0.7.11/examples/while-loop.js 0000664 0000000 0000000 00000000747 13500662733 0017630 0 ustar 00root root 0000000 0000000 "use strict";
// While loops are usually constructruted as recurrent asynchronous functions:
var deferred = require("deferred")
, count = 0
, limit = 10
, get;
get = function () {
var d = deferred();
setTimeout(function () { d.resolve(++count); }, 500);
return d.promise;
};
// Invoke while loop:
get()
.then(function self(value) {
console.log(value);
if (value < limit) return get().then(self);
return value;
})
.done(function () { console.log("Done!"); });
deferred-0.7.11/ext/ 0000775 0000000 0000000 00000000000 13500662733 0014165 5 ustar 00root root 0000000 0000000 deferred-0.7.11/ext/_process-arguments.js 0000664 0000000 0000000 00000001515 13500662733 0020345 0 ustar 00root root 0000000 0000000 "use strict";
var arrayOf = require("es5-ext/array/of")
, isValue = require("es5-ext/object/is-value")
, deferred = require("../deferred")
, isPromise = require("../is-promise")
, assimilate = require("../assimilate");
var push = Array.prototype.push, slice = Array.prototype.slice;
module.exports = function (args, length) {
var i, arg;
if (isValue(length) && args.length !== length) {
args = slice.call(args, 0, length);
if (args.length < length) {
push.apply(args, new Array(length - args.length));
}
} else {
length = args.length;
}
for (i = 0; i < length; ++i) {
arg = assimilate(args[i]);
if (isPromise(arg)) {
if (!arg.resolved) {
if (length > 1) return deferred.apply(null, args);
return arg(arrayOf);
}
if (arg.failed) return arg;
args[i] = arg.value;
}
}
return args;
};
deferred-0.7.11/ext/array/ 0000775 0000000 0000000 00000000000 13500662733 0015303 5 ustar 00root root 0000000 0000000 deferred-0.7.11/ext/array/every.js 0000664 0000000 0000000 00000000150 13500662733 0016767 0 ustar 00root root 0000000 0000000 // Promise aware Array's every
"use strict";
module.exports = require("../../lib/some-every")(false);
deferred-0.7.11/ext/array/find.js 0000664 0000000 0000000 00000004473 13500662733 0016571 0 ustar 00root root 0000000 0000000 // Promise aware Array's find
// Additionally differs from some that it returns *first in order* item that matches constraint
"use strict";
var assign = require("es5-ext/object/assign")
, isValue = require("es5-ext/object/is-value")
, ensureValue = require("es5-ext/object/valid-value")
, callable = require("es5-ext/object/valid-callable")
, toNaturalNumber = require("es5-ext/number/to-pos-integer")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, assimilate = require("../../assimilate");
var call = Function.prototype.call, resolve = deferred.resolve, Find;
Find = function (list, cb, context) {
this.list = list;
this.cb = cb;
this.context = context;
this.length = toNaturalNumber(list.length);
while (this.current < this.length) {
if (this.current in list) {
assign(this, deferred());
this.processCb = this.processCb.bind(this);
this.process();
return this.promise;
}
++this.current;
}
return resolve(undefined);
};
Find.prototype = {
current: 0,
process: function () {
var value = assimilate(this.list[this.current]);
if (isPromise(value)) {
if (!value.resolved) {
value.done(this.processCb, this.reject);
return;
}
if (value.failed) {
this.reject(value.value);
return;
}
value = value.value;
}
this.processCb(value);
},
processCb: function (listValue) {
var value;
if (this.cb) {
try {
value = call.call(this.cb, this.context, listValue, this.current, this.list);
} catch (e) {
this.reject(e);
return;
}
value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
value.done(this.processValue.bind(this, listValue), this.reject);
return;
}
if (value.failed) {
this.reject(value.value);
return;
}
value = value.value;
}
} else {
value = listValue;
}
this.processValue(listValue, value);
},
processValue: function (listValue, value) {
if (value) {
this.resolve(listValue);
return;
}
while (++this.current < this.length) {
if (this.current in this.list) {
this.process();
return;
}
}
this.resolve(undefined);
}
};
module.exports = function (cb/*, thisArg*/) {
ensureValue(this);
if (isValue(cb)) callable(cb);
return new Find(this, cb, arguments[1]);
};
deferred-0.7.11/ext/array/map.js 0000664 0000000 0000000 00000004260 13500662733 0016420 0 ustar 00root root 0000000 0000000 // Promise aware Array's map
"use strict";
var assign = require("es5-ext/object/assign")
, isValue = require("es5-ext/object/is-value")
, ensureValue = require("es5-ext/object/valid-value")
, callable = require("es5-ext/object/valid-callable")
, toNaturalNumber = require("es5-ext/number/to-pos-integer")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, assimilate = require("../../assimilate");
var every = Array.prototype.every, call = Function.prototype.call, DMap;
DMap = function (list, cb, context) {
this.list = list;
this.cb = cb;
this.context = context;
this.result = new Array(toNaturalNumber(list.length));
assign(this, deferred());
every.call(list, this.process, this);
if (!this.waiting) return this.resolve(this.result);
this.initialized = true;
return this.promise;
};
DMap.prototype = {
waiting: 0,
initialized: false,
process: function (value, index) {
++this.waiting;
value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
value.done(this.processCb.bind(this, index), this.reject);
return true;
}
if (value.failed) {
this.reject(value.value);
return false;
}
value = value.value;
}
return this.processCb(index, value);
},
processCb: function (index, value) {
if (this.promise.resolved) return false;
if (this.cb) {
try {
value = call.call(this.cb, this.context, value, index, this.list);
} catch (e) {
this.reject(e);
return false;
}
value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
value.done(this.processValue.bind(this, index), this.reject);
return true;
}
if (value.failed) {
this.reject(value.value);
return false;
}
value = value.value;
}
}
this.processValue(index, value);
return true;
},
processValue: function (index, value) {
if (this.promise.resolved) return;
this.result[index] = value;
if (!--this.waiting && this.initialized) this.resolve(this.result);
}
};
module.exports = function (cb/*, thisArg*/) {
ensureValue(this);
if (isValue(cb)) callable(cb);
return new DMap(this, cb, arguments[1]);
};
deferred-0.7.11/ext/array/reduce.js 0000664 0000000 0000000 00000007142 13500662733 0017114 0 ustar 00root root 0000000 0000000 // Promise aware Array's reduce
"use strict";
var assign = require("es5-ext/object/assign")
, isValue = require("es5-ext/object/is-value")
, ensureValue = require("es5-ext/object/valid-value")
, callable = require("es5-ext/object/valid-callable")
, toNaturalNumber = require("es5-ext/number/to-pos-integer")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, assimilate = require("../../assimilate");
var call = Function.prototype.call, resolve = deferred.resolve, Reduce;
Reduce = function (list, cb, initial, initialized) {
this.list = list;
this.cb = cb;
this.initialized = initialized;
this.length = toNaturalNumber(list.length);
initial = assimilate(initial);
if (isPromise(initial)) {
if (!initial.resolved) {
assign(this, deferred());
initial.done(
function (resolvedInitial) {
this.value = resolvedInitial;
this.init();
}.bind(this),
this.reject
);
return this.promise;
}
this.value = initial.value;
if (initial.failed) return initial;
} else {
this.value = initial;
}
return this.init();
};
Reduce.prototype = {
current: 0,
state: false,
init: function () {
while (this.current < this.length) {
if (hasOwnProperty.call(this.list, this.current)) break;
++this.current;
}
if (this.current === this.length) {
if (!this.initialized) {
throw new Error("Reduce of empty array with no initial value");
}
return this.resolve ? this.resolve(this.value) : resolve(this.value);
}
if (!this.promise) assign(this, deferred());
this.processCb = this.processCb.bind(this);
this.processValue = this.processValue.bind(this);
this.continue();
return this.promise;
},
continue: function () {
var result;
while (!this.state) {
result = this.process();
if (this.state !== "cb") break;
result = this.processCb(result);
if (this.state !== "value") break;
this.processValue(result);
}
},
process: function () {
var value = assimilate(this.list[this.current]);
if (isPromise(value)) {
if (!value.resolved) {
value.done(
function (result) {
result = this.processCb(result);
if (this.state !== "value") return;
this.processValue(result);
if (!this.state) this.continue();
}.bind(this),
this.reject
);
return null;
}
if (value.failed) {
this.reject(value.value);
return null;
}
value = value.value;
}
this.state = "cb";
return value;
},
processCb: function (value) {
if (!this.initialized) {
this.initialized = true;
this.state = "value";
return value;
}
if (this.cb) {
try {
value = call.call(this.cb, undefined, this.value, value, this.current, this.list);
} catch (e) {
this.reject(e);
return null;
}
value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
value.done(
function (result) {
this.state = "value";
this.processValue(result);
if (!this.state) this.continue();
}.bind(this),
this.reject
);
return null;
}
if (value.failed) {
this.reject(value.value);
return null;
}
value = value.value;
}
}
this.state = "value";
return value;
},
processValue: function (value) {
this.value = value;
while (++this.current < this.length) {
if (hasOwnProperty.call(this.list, this.current)) {
this.state = false;
return;
}
}
this.resolve(this.value);
}
};
module.exports = function (cb/*, initial*/) {
ensureValue(this);
if (isValue(cb)) callable(cb);
return new Reduce(this, cb, arguments[1], arguments.length > 1);
};
deferred-0.7.11/ext/array/some.js 0000664 0000000 0000000 00000000146 13500662733 0016605 0 ustar 00root root 0000000 0000000 // Promise aware Array's some
"use strict";
module.exports = require("../../lib/some-every")(true);
deferred-0.7.11/ext/function/ 0000775 0000000 0000000 00000000000 13500662733 0016012 5 ustar 00root root 0000000 0000000 deferred-0.7.11/ext/function/call-async.js 0000664 0000000 0000000 00000003135 13500662733 0020400 0 ustar 00root root 0000000 0000000 // Call asynchronous function
"use strict";
var toArray = require("es5-ext/array/to-array")
, isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, processArguments = require("../_process-arguments");
var slice = Array.prototype.slice, apply = Function.prototype.apply, applyFn, callAsync;
applyFn = function (fn, args, def) {
args = toArray(args);
apply.call(
fn,
this,
args.concat(function (error, result) {
if (isValue(error)) def.reject(error);
else def.resolve(arguments.length > 2 ? slice.call(arguments, 1) : result);
})
);
};
callAsync = function (fn, length, context, args) {
var def;
args = processArguments(args, length);
if (isPromise(args)) {
if (args.failed) return args;
def = deferred();
args.done(function (resolvedArgs) {
if (fn.returnsPromise) {
apply.call(fn, context, resolvedArgs);
return;
}
try { applyFn.call(context, fn, resolvedArgs, def); } catch (e) { def.reject(e); }
}, def.reject);
return def.promise;
}
if (fn.returnsPromise) return apply.call(fn, context, args);
def = deferred();
try {
applyFn.call(context, fn, args, def);
} catch (e) {
def.reject(e);
throw e;
}
return def.promise;
};
module.exports = exports = function (context/*, …args*/) {
return callAsync(callable(this), null, context, slice.call(arguments, 1));
};
Object.defineProperty(exports, "_base", {
configurable: true,
enumerable: false,
writable: true,
value: callAsync
});
deferred-0.7.11/ext/function/delay.js 0000664 0000000 0000000 00000001707 13500662733 0017453 0 ustar 00root root 0000000 0000000 // Delay function execution, return promise for delayed function result
"use strict";
var isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, nextTick = require("next-tick")
, ensureTimeout = require("timers-ext/valid-timeout")
, deferred = require("../../deferred");
var apply = Function.prototype.apply, delayed;
delayed = function (fn, args, resolve, reject) {
var value;
try {
value = apply.call(fn, this, args);
} catch (e) {
reject(e);
return;
}
resolve(value);
};
module.exports = function (timeout) {
var fn, result, delay;
fn = callable(this);
if (isValue(timeout)) {
timeout = ensureTimeout(timeout);
delay = setTimeout;
} else {
delay = nextTick;
}
result = function () {
var def = deferred();
delay(delayed.bind(this, fn, arguments, def.resolve, def.reject), timeout);
return def.promise;
};
result.returnsPromise = true;
return result;
};
deferred-0.7.11/ext/function/gate.js 0000664 0000000 0000000 00000004464 13500662733 0017300 0 ustar 00root root 0000000 0000000 /* eslint max-statements: "off" */
// Limit number of concurrent function executions (to cLimit number).
// Limited calls are queued. Optionaly maximum queue length can also be
// controlled with qLimit value, any calls that would reach over that limit
// would be discarded (its promise would resolve with "Too many calls" error)
"use strict";
var toPosInt = require("es5-ext/number/to-pos-integer")
, callable = require("es5-ext/object/valid-callable")
, isValue = require("es5-ext/object/is-value")
, eeUnify = require("event-emitter/unify")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, assimilate = require("../../assimilate");
var resolve = deferred.resolve
, reject = deferred.reject
, apply = Function.prototype.apply
, max = Math.max
, gateReject;
require("../promise/finally");
gateReject = function () {
var e = new Error("Too many calls at the gate");
e.code = "DEFERRED_REJECTED_AT_GATE";
e.type = "deferred-gate-rejected";
return reject(e);
};
module.exports = function (cLimit, qLimit) {
var fn, count, decrement, unload, queue, run, result;
fn = callable(this);
cLimit = max(toPosInt(cLimit), 1);
qLimit = !isValue(qLimit) || isNaN(qLimit) ? Infinity : toPosInt(qLimit);
count = 0;
queue = [];
run = function (thisArg, args, def) {
var localResult;
try {
localResult = apply.call(fn, thisArg, args);
} catch (e) {
if (!def) return reject(e);
def.reject(e);
return unload();
}
localResult = assimilate(localResult);
if (isPromise(localResult)) {
if (def) eeUnify(def.promise, localResult);
if (!localResult.resolved) {
++count;
if (def) def.resolve(localResult);
return localResult.finally(decrement);
}
if (!localResult.failed) localResult = localResult.value;
}
if (!def) return resolve(localResult);
def.resolve(localResult);
return unload();
};
decrement = function () {
--count;
unload();
};
unload = function () {
var data;
if ((data = queue.shift())) run.apply(null, data);
};
result = function () {
var def;
if (count >= cLimit) {
if (queue.length < qLimit) {
def = deferred();
queue.push([this, arguments, def]);
return def.promise;
}
return gateReject();
}
return run(this, arguments);
};
result.returnsPromise = true;
return result;
};
deferred-0.7.11/ext/function/promisify-sync.js 0000664 0000000 0000000 00000002362 13500662733 0021346 0 ustar 00root root 0000000 0000000 // Promisify synchronous function
"use strict";
var isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, toNaturalNumber = require("es5-ext/number/to-pos-integer")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, processArguments = require("../_process-arguments");
var apply = Function.prototype.apply, applyFn;
applyFn = function (fn, args, resolve, reject) {
var value;
try {
value = apply.call(fn, this, args);
} catch (e) {
reject(e);
return;
}
resolve(value);
};
module.exports = function (length) {
var fn, result;
fn = callable(this);
if (fn.returnsPromise) return fn;
if (isValue(length)) length = toNaturalNumber(length);
result = function () {
var args, def;
args = processArguments(arguments, length);
if (isPromise(args)) {
if (args.failed) return args;
def = deferred();
args.done(
function (resolvedArgs) {
applyFn.call(this, fn, resolvedArgs, def.resolve, def.reject);
}.bind(this),
def.reject
);
} else {
def = deferred();
applyFn.call(this, fn, args, def.resolve, def.reject);
}
return def.promise;
};
result.returnsPromise = true;
return result;
};
deferred-0.7.11/ext/function/promisify.js 0000664 0000000 0000000 00000001103 13500662733 0020364 0 ustar 00root root 0000000 0000000 // Promisify asynchronous function
"use strict";
var isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, toNaturalNumber = require("es5-ext/number/to-pos-integer")
, callAsync = require("./call-async")._base;
module.exports = function (length) {
var fn, result;
fn = callable(this);
if (fn.returnsPromise) return fn;
if (isValue(length)) length = toNaturalNumber(length);
result = function () { return callAsync(fn, length, this, arguments); };
result.returnsPromise = true;
return result;
};
deferred-0.7.11/ext/promise/ 0000775 0000000 0000000 00000000000 13500662733 0015643 5 ustar 00root root 0000000 0000000 deferred-0.7.11/ext/promise/_array.js 0000664 0000000 0000000 00000001733 13500662733 0017462 0 ustar 00root root 0000000 0000000 // Used by promise extensions that are based on array extensions.
"use strict";
var isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, deferred = require("../../deferred");
var deferredReject = deferred.reject;
module.exports = function (name, ext) {
deferred.extend(
name,
function (cb) {
var def;
if (isValue(cb)) callable(cb);
if (!this.pending) this.pending = [];
def = deferred();
this.pending.push(name, [arguments, def.resolve, def.reject]);
return def.promise;
},
function (args, resolve, reject) {
var result;
if (this.failed) {
reject(this.value);
return;
}
try {
result = ext.apply(this.value, args);
} catch (e) {
reject(e);
return;
}
resolve(result);
},
function (cb) {
if (isValue(cb)) callable(cb);
if (this.failed) return this;
try { return ext.apply(this.value, arguments); }
catch (e) { return deferredReject(e); }
}
);
};
deferred-0.7.11/ext/promise/aside.js 0000664 0000000 0000000 00000001732 13500662733 0017271 0 ustar 00root root 0000000 0000000 // 'aside' - Promise extension
//
// promise.aside(win, fail)
//
// Works in analogous way as promise function itself (or `then`)
// but instead of adding promise to promise chain it returns context promise and
// lets callback carry on with other processing logic
"use strict";
var isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, deferred = require("../../deferred");
deferred.extend(
"aside",
function (win, fail) {
if (isValue(win)) callable(win);
if (isValue(fail)) callable(fail);
if (win || fail) {
if (!this.pending) {
this.pending = [];
}
this.pending.push("aside", arguments);
}
return this;
},
function (win, fail) {
var cb = this.failed ? fail : win;
if (cb) {
cb(this.value);
}
},
function (win, fail) {
var cb;
if (isValue(win)) callable(win);
if (isValue(fail)) callable(fail);
cb = this.failed ? fail : win;
if (cb) {
cb(this.value);
}
return this;
}
);
deferred-0.7.11/ext/promise/catch.js 0000664 0000000 0000000 00000002544 13500662733 0017270 0 ustar 00root root 0000000 0000000 // 'catch' - Promise extension
//
// promise.catch(cb)
//
// Same as `then` but accepts only onFail callback
"use strict";
var isCallable = require("es5-ext/object/is-callable")
, validValue = require("es5-ext/object/valid-value")
, deferred = require("../../deferred")
, 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, def.reject]);
return def.promise;
},
function (cb, localResolve, localReject) {
var value;
if (!this.failed) {
localResolve(this.value);
return;
}
if (isCallable(cb)) {
if (isPromise(cb)) {
if (cb.resolved) {
if (cb.failed) localReject(cb.value);
else localResolve(cb.value);
} else {
cb.done(localResolve, localReject);
}
return;
}
try {
value = cb(this.value);
} catch (e) {
localReject(e);
return;
}
localResolve(value);
return;
}
localResolve(cb);
},
function (cb) {
var value;
validValue(cb);
if (!this.failed) return this;
if (isCallable(cb)) {
if (isPromise(cb)) return cb;
try { value = cb(this.value); }
catch (e) { return reject(e); }
return resolve(value);
}
return resolve(cb);
}
);
deferred-0.7.11/ext/promise/cb.js 0000664 0000000 0000000 00000002612 13500662733 0016566 0 ustar 00root root 0000000 0000000 // 'cb' - Promise extension
//
// promise.cb(cb)
//
// Handles asynchronous function style callback (which is run in next event loop
// the earliest). Returns self promise. Callback is optional.
//
// Useful when we want to configure typical asynchronous function which logic is
// internally configured with promises.
//
// Extension can be used as follows:
//
// var foo = function (arg1, arg2, cb) {
// var d = deferred();
// // ... implementation
// return d.promise.cb(cb);
// };
//
// `cb` extension returns promise and handles eventual callback (optional)
"use strict";
var isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, nextTick = require("next-tick")
, deferred = require("../../deferred");
deferred.extend(
"cb",
function (cb) {
if (!isValue(cb)) return this;
callable(cb);
nextTick(
function () {
if (this.resolved) {
if (this.failed) cb(this.value);
else cb(null, this.value);
} else {
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);
},
function (cb) {
if (!isValue(cb)) return this;
callable(cb);
nextTick(
function () {
if (this.failed) cb(this.value);
else cb(null, this.value);
}.bind(this)
);
return this;
}
);
deferred-0.7.11/ext/promise/finally.js 0000664 0000000 0000000 00000001015 13500662733 0017634 0 ustar 00root root 0000000 0000000 // 'finally' - Promise extension
//
// promise.finally(cb)
//
// Called on promise resolution returns same promise, doesn't pass any values to
// provided callback
"use strict";
var callable = require("es5-ext/object/valid-callable")
, deferred = require("../../deferred");
deferred.extend(
"finally",
function (cb) {
callable(cb);
if (!this.pending) this.pending = [];
this.pending.push("finally", arguments);
return this;
},
function (cb) { cb(); },
function (cb) {
callable(cb)();
return this;
}
);
deferred-0.7.11/ext/promise/get.js 0000664 0000000 0000000 00000002074 13500662733 0016763 0 ustar 00root root 0000000 0000000 // 'get' - Promise extension
//
// promise.get(name)
//
// Resolves with property of resolved object
"use strict";
var value = require("es5-ext/object/valid-value")
, deferred = require("../../deferred");
var reduce = Array.prototype.reduce, resolve = deferred.resolve, reject = deferred.reject;
deferred.extend(
"get",
function (/* …name*/) {
var def;
if (!this.pending) this.pending = [];
def = deferred();
this.pending.push("get", [arguments, def.resolve, def.reject]);
return def.promise;
},
function (args, localResolve, localReject) {
var result;
if (this.failed) localReject(this.value);
try {
result = reduce.call(
args, function (obj, key) { return value(obj)[String(key)]; }, this.value
);
} catch (e) {
localReject(e);
return;
}
localResolve(result);
},
function (/* …name*/) {
var result;
if (this.failed) return this;
try {
result = reduce.call(
arguments, function (obj, key) { return value(obj)[String(key)]; }, this.value
);
}
catch (e) { return reject(e); }
return resolve(result);
}
);
deferred-0.7.11/ext/promise/invoke-async.js 0000664 0000000 0000000 00000006341 13500662733 0020613 0 ustar 00root root 0000000 0000000 /* eslint max-statements: "off" */
// 'invokeAsync' - Promise extension
//
// promise.invokeAsync(name[, arg0[, arg1[, ...]]])
//
// On resolved object calls asynchronous method that takes callback
// (Node.js style).
// Do not pass callback, it's handled by internal implementation.
// 'name' can be method name or method itself.
"use strict";
var toArray = require("es5-ext/array/to-array")
, isValue = require("es5-ext/object/is-value")
, isCallable = require("es5-ext/object/is-callable")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, processArguments = require("../_process-arguments");
var slice = Array.prototype.slice
, apply = Function.prototype.apply
, reject = deferred.reject
, applyFn;
applyFn = function (fn, args, localResolve, localReject) {
var result;
if (fn.returnsPromise) {
try {
result = apply.call(fn, this, args);
} catch (e) {
localReject(e);
return;
}
localResolve(result);
return;
}
args = toArray(args).concat(function (error, localResult) {
if (isValue(error)) {
localReject(error);
} else {
localResolve(arguments.length > 2 ? slice.call(arguments, 1) : localResult);
}
});
try { apply.call(fn, this, args); }
catch (e2) { localReject(e2); }
};
deferred.extend(
"invokeAsync",
function (methodIgnored/*, …args*/) {
var def;
if (!this.pending) this.pending = [];
def = deferred();
this.pending.push("invokeAsync", [arguments, def.resolve, def.reject]);
return def.promise;
},
function (args, localResolve, localReject) {
var fn;
if (this.failed) {
localReject(this.value);
return;
}
if (!isValue(this.value)) {
localReject(new TypeError("Cannot use null or undefined"));
return;
}
fn = args[0];
if (!isCallable(fn)) {
fn = String(fn);
if (!isCallable(this.value[fn])) {
localReject(new TypeError(fn + " is not a function"));
return;
}
fn = this.value[fn];
}
args = processArguments(slice.call(args, 1));
if (isPromise(args)) {
if (args.failed) {
localReject(args.value);
return;
}
args.done(
function (argsResolved) {
applyFn.call(this, fn, argsResolved, localResolve, localReject);
}.bind(this.value),
localReject
);
} else {
applyFn.call(this.value, fn, args, localResolve, localReject);
}
},
function (method/*, …args*/) {
var args, def;
if (this.failed) return this;
if (!isValue(this.value)) {
return reject(new TypeError("Cannot use null or undefined"));
}
if (!isCallable(method)) {
method = String(method);
if (!isCallable(this.value[method])) {
return reject(new TypeError(method + " is not a function"));
}
method = this.value[method];
}
args = processArguments(slice.call(arguments, 1));
if (isPromise(args)) {
if (args.failed) return args;
def = deferred();
args.done(
function (argsResolved) {
applyFn.call(this, method, argsResolved, def.resolve, def.reject);
}.bind(this.value),
def.reject
);
} else if (method.returnsPromise) {
return applyFn.call(this.value, method, args, deferred, reject);
} else {
def = deferred();
applyFn.call(this.value, method, args, def.resolve, def.reject);
}
return def.promise;
}
);
deferred-0.7.11/ext/promise/invoke.js 0000664 0000000 0000000 00000005145 13500662733 0017501 0 ustar 00root root 0000000 0000000 /* eslint max-statements: "off" */
// 'invoke' - Promise extension
//
// promise.invoke(name[, arg0[, arg1[, ...]]])
//
// On resolved object calls method that returns immediately.
// 'name' can be method name or method itself.
"use strict";
var isValue = require("es5-ext/object/is-value")
, isCallable = require("es5-ext/object/is-callable")
, deferred = require("../../deferred")
, isPromise = require("../../is-promise")
, processArguments = require("../_process-arguments");
var slice = Array.prototype.slice
, apply = Function.prototype.apply
, reject = deferred.reject
, applyFn;
applyFn = function (fn, args, localResolve, localReject) {
var value;
try { value = apply.call(fn, this, args); }
catch (e) { return localReject(e); }
return localResolve(value);
};
deferred.extend(
"invoke",
function (methodIgnored/*, …args*/) {
var def;
if (!this.pending) this.pending = [];
def = deferred();
this.pending.push("invoke", [arguments, def.resolve, def.reject]);
return def.promise;
},
function (args, localResolve, localReject) {
var fn;
if (this.failed) {
localReject(this.value);
return;
}
if (!isValue(this.value)) {
localReject(new TypeError("Cannot use null or undefined"));
return;
}
fn = args[0];
if (!isCallable(fn)) {
fn = String(fn);
if (!isCallable(this.value[fn])) {
localReject(new TypeError(fn + " is not a function"));
return;
}
fn = this.value[fn];
}
args = processArguments(slice.call(args, 1));
if (isPromise(args)) {
if (args.failed) {
localReject(args.value);
return;
}
args.done(
function (argsResolved) {
applyFn.call(this, fn, argsResolved, localResolve, localReject);
}.bind(this.value),
localReject
);
} else {
applyFn.call(this.value, fn, args, localResolve, localReject);
}
},
function (method/*, …args*/) {
var args, def;
if (this.failed) return this;
if (!isValue(this.value)) {
return reject(new TypeError("Cannot use null or undefined"));
}
if (!isCallable(method)) {
method = String(method);
if (!isCallable(this.value[method])) {
return reject(new TypeError(method + " is not a function"));
}
method = this.value[method];
}
args = processArguments(slice.call(arguments, 1));
if (isPromise(args)) {
if (args.failed) return args;
def = deferred();
args.done(
function (argsResolved) {
applyFn.call(this, method, argsResolved, def.resolve, def.reject);
}.bind(this.value),
def.reject
);
return def.promise;
}
return applyFn.call(this.value, method, args, deferred, reject);
}
);
deferred-0.7.11/ext/promise/map.js 0000664 0000000 0000000 00000000305 13500662733 0016754 0 ustar 00root root 0000000 0000000 // 'map' - Promise extension
//
// promise.map(fn[, thisArg[, concurrentLimit]])
//
// Promise aware map for array-like results
"use strict";
require("./_array")("map", require("../array/map"));
deferred-0.7.11/ext/promise/reduce.js 0000664 0000000 0000000 00000000301 13500662733 0017442 0 ustar 00root root 0000000 0000000 // 'reduce' - Promise extension
//
// promise.reduce(fn[, initial])
//
// Promise aware reduce for array-like results
"use strict";
require("./_array")("reduce", require("../array/reduce"));
deferred-0.7.11/ext/promise/some.js 0000664 0000000 0000000 00000000267 13500662733 0017151 0 ustar 00root root 0000000 0000000 // 'some' - Promise extension
//
// promise.some(fn[, thisArg])
//
// Promise aware some for array-like results
"use strict";
require("./_array")("some", require("../array/some"));
deferred-0.7.11/ext/promise/spread.js 0000664 0000000 0000000 00000003456 13500662733 0017467 0 ustar 00root root 0000000 0000000 // 'spread' - Promise extensions
//
// promise.spread(onsuccess, onerror)
//
// Matches eventual list result onto function arguments,
// otherwise works same as 'then' (promise function itself)
"use strict";
var spread = require("es5-ext/function/#/spread")
, isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, isCallable = require("es5-ext/object/is-callable")
, isPromise = require("../../is-promise")
, deferred = require("../../deferred");
var resolve = deferred.resolve, reject = deferred.reject;
deferred.extend(
"spread",
function (win, fail) {
var def;
if (isValue(win)) callable(win);
if (!win && !isValue(fail)) return this;
if (!this.pending) this.pending = [];
def = deferred();
this.pending.push("spread", [win, fail, def.resolve, def.reject]);
return def.promise;
},
function (win, fail, localResolve, localReject) {
var cb, value;
cb = this.failed ? fail : win;
if (!isValue(cb)) {
if (this.failed) localReject(this.value);
else localResolve(this.value);
}
if (isCallable(cb)) {
if (isPromise(cb)) {
if (cb.resolved) {
if (cb.failed) localReject(cb.value);
else localResolve(cb.value);
} else {
cb.done(localResolve, localReject);
}
return;
}
if (!this.failed) cb = spread.call(cb);
try {
value = cb(this.value);
} catch (e) {
localReject(e);
return;
}
localResolve(value);
} else {
localResolve(cb);
}
},
function (win, fail) {
var cb, value;
cb = this.failed ? fail : win;
if (!isValue(cb)) return this;
if (isCallable(cb)) {
if (isPromise(cb)) return cb;
if (!this.failed) cb = spread.call(cb);
try { value = cb(this.value); }
catch (e) { return reject(e); }
return resolve(value);
}
return resolve(cb);
}
);
deferred-0.7.11/ext/promise/timeout.js 0000664 0000000 0000000 00000002101 13500662733 0017661 0 ustar 00root root 0000000 0000000 // 'timeout' - Promise extension
//
// promise.timeout(ms)
//
// Resolves with resolution value of context promise assuming it settles before timeout time passes
// Otherwise resolves with timeout rejection
"use strict";
var customError = require("es5-ext/error/custom")
, isValue = require("es5-ext/object/is-value")
, nextTick = require("next-tick")
, ensureTimeout = require("timers-ext/valid-timeout")
, deferred = require("../../deferred");
deferred.extend(
"timeout",
function (timeout) {
var def;
var callback = function () {
if (this.resolved) return;
def.reject(customError("Operation timeout", "DEFERRED_TIMEOUT"));
}.bind(this);
if (isValue(timeout)) setTimeout(callback, ensureTimeout(timeout));
else nextTick(callback);
if (!this.pending) this.pending = [];
def = deferred();
this.pending.push("timeout", [def.promise, def.resolve]);
return def.promise;
},
function (promise, resolve) { if (!promise.resolved) resolve(this); },
function (timeout) {
if (isValue(timeout)) ensureTimeout(timeout);
return this;
}
);
deferred-0.7.11/index.js 0000664 0000000 0000000 00000002723 13500662733 0015036 0 ustar 00root root 0000000 0000000 // This construct deferred with all needed goodies that are being exported
// when we import 'deferred' by main name.
// All available promise extensions are also initialized.
"use strict";
var call = Function.prototype.call
, assign = require("es5-ext/object/assign");
module.exports = assign(
require("./deferred"),
{
invokeAsync: require("./invoke-async"),
isPromise: require("./is-promise"),
dynamicQueue: require("./dynamic-queue"),
validPromise: require("./valid-promise"),
callAsync: call.bind(require("./ext/function/call-async")),
delay: call.bind(require("./ext/function/delay")),
gate: call.bind(require("./ext/function/gate")),
monitor: require("./monitor"),
promisify: call.bind(require("./ext/function/promisify")),
promisifySync: call.bind(require("./ext/function/promisify-sync")),
every: call.bind(require("./ext/array/every")),
find: call.bind(require("./ext/array/find")),
map: call.bind(require("./ext/array/map")),
reduce: call.bind(require("./ext/array/reduce")),
some: call.bind(require("./ext/array/some"))
},
require("./profiler")
);
require("./ext/promise/aside");
require("./ext/promise/catch");
require("./ext/promise/cb");
require("./ext/promise/finally");
require("./ext/promise/get");
require("./ext/promise/invoke");
require("./ext/promise/invoke-async");
require("./ext/promise/map");
require("./ext/promise/reduce");
require("./ext/promise/spread");
require("./ext/promise/some");
require("./ext/promise/timeout");
deferred-0.7.11/invoke-async.js 0000664 0000000 0000000 00000000752 13500662733 0016335 0 ustar 00root root 0000000 0000000 // Invoke asynchronous function
"use strict";
var isCallable = require("es5-ext/object/is-callable")
, callable = require("es5-ext/object/valid-callable")
, value = require("es5-ext/object/valid-value")
, callAsync = require("./ext/function/call-async")._base
, slice = Array.prototype.slice;
module.exports = function (obj, fn/*, …args*/) {
value(obj);
if (!isCallable(fn)) fn = callable(obj[fn]);
return callAsync(fn, null, obj, slice.call(arguments, 2));
};
deferred-0.7.11/is-promise.js 0000664 0000000 0000000 00000000310 13500662733 0016004 0 ustar 00root root 0000000 0000000 // Whether given object is a promise
"use strict";
module.exports = function (value) {
return (
typeof value === "function" && typeof value.then === "function" && value.end !== value.done
);
};
deferred-0.7.11/lib/ 0000775 0000000 0000000 00000000000 13500662733 0014133 5 ustar 00root root 0000000 0000000 deferred-0.7.11/lib/some-every.js 0000664 0000000 0000000 00000005725 13500662733 0016575 0 ustar 00root root 0000000 0000000 // Promise aware Array's some
"use strict";
var assign = require("es5-ext/object/assign")
, isValue = require("es5-ext/object/is-value")
, ensureValue = require("es5-ext/object/valid-value")
, callable = require("es5-ext/object/valid-callable")
, toNaturalNumber = require("es5-ext/number/to-pos-integer")
, deferred = require("../deferred")
, isPromise = require("../is-promise")
, assimilate = require("../assimilate");
var call = Function.prototype.call, resolve = deferred.resolve;
module.exports = function (resolvent) {
var Iterator = function (list, cb, context) {
this.list = list;
this.cb = cb;
this.context = context;
this.length = toNaturalNumber(list.length);
while (this.current < this.length) {
if (this.current in list) {
assign(this, deferred());
this.processCb = this.processCb.bind(this);
this.processValue = this.processValue.bind(this);
this.continue();
return this.promise;
}
++this.current;
}
return resolve(!resolvent);
};
Iterator.prototype = {
current: 0,
state: false,
continue: function () {
var result;
while (!this.state) {
result = this.process();
if (this.state !== "cb") break;
result = this.processCb(result);
if (this.state !== "value") break;
this.processValue(result);
}
},
process: function () {
var value = assimilate(this.list[this.current]);
if (isPromise(value)) {
if (!value.resolved) {
value.done(
function (result) {
result = this.processCb(result);
if (this.state !== "value") return;
this.processValue(result);
if (!this.state) this.continue();
}.bind(this),
this.reject
);
return null;
}
if (value.failed) {
this.reject(value.value);
return null;
}
value = value.value;
}
this.state = "cb";
return value;
},
processCb: function (value) {
if (this.cb) {
try {
value = call.call(this.cb, this.context, value, this.current, this.list);
} catch (e) {
this.reject(e);
return null;
}
value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
value.done(
function (result) {
this.state = "value";
this.processValue(result);
if (!this.state) this.continue();
}.bind(this),
this.reject
);
return null;
}
if (value.failed) {
this.reject(value.value);
return null;
}
value = value.value;
}
}
this.state = "value";
return value;
},
processValue: function (value) {
if (Boolean(value) === resolvent) {
this.resolve(resolvent);
return;
}
while (++this.current < this.length) {
if (this.current in this.list) {
this.state = false;
return;
}
}
this.resolve(!resolvent);
}
};
return function (cb/*, thisArg*/) {
ensureValue(this);
if (isValue(cb)) callable(cb);
return new Iterator(this, cb, arguments[1]);
};
};
deferred-0.7.11/monitor.js 0000664 0000000 0000000 00000002212 13500662733 0015407 0 ustar 00root root 0000000 0000000 /* eslint no-console: "off" */
// Run if you want to monitor unresolved promises (in properly working
// application there should be no promises that are never resolved)
"use strict";
var max = Math.max
, isValue = require("es5-ext/object/is-value")
, callable = require("es5-ext/object/valid-callable")
, isCallable = require("es5-ext/object/is-callable")
, toPosInt = require("es5-ext/number/to-pos-integer")
, deferred = require("./deferred");
exports = module.exports = function (timeout, cb) {
if (timeout === false) {
// Cancel monitor
delete deferred._monitor;
delete exports.timeout;
delete exports.callback;
return;
}
exports.timeout = timeout = max(toPosInt(timeout) || 5000, 50);
if (isValue(cb)) {
callable(cb);
} else if (typeof console !== "undefined" && console && isCallable(console.error)) {
cb = function (e) {
console.error(
(e.stack && e.stack.toString()) || "Unresolved promise: no stack available"
);
};
}
exports.callback = cb;
deferred._monitor = function () {
var e = new Error("Unresolved promise");
return setTimeout(function () { if (cb) cb(e); }, timeout);
};
};
deferred-0.7.11/package.json 0000664 0000000 0000000 00000003320 13500662733 0015651 0 ustar 00root root 0000000 0000000 {
"name": "deferred",
"version": "0.7.11",
"description": "Modular and fast Promises implementation",
"author": "Mariusz Nowak (http://www.medikoo.com/)",
"keywords": [
"async",
"asynchronous",
"deferred",
"flow",
"future",
"futures",
"promise",
"promises",
"continuations"
],
"repository": {
"type": "git",
"url": "git://github.com/medikoo/deferred.git"
},
"dependencies": {
"d": "^1.0.1",
"es5-ext": "^0.10.50",
"event-emitter": "^0.3.5",
"next-tick": "^1.0.0",
"timers-ext": "^0.1.7"
},
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-medikoo": "^2.3.0",
"git-list-updated": "^1.1.2",
"husky": "^2.4.1",
"lint-staged": "^8.2.1",
"prettier-elastic": "^1.18.2",
"tad": "^2.0.1"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"eslint"
],
"*.{css,html,js,json,md,yaml,yml}": [
"prettier -c"
]
},
"eslintConfig": {
"extends": "medikoo/es5",
"root": true,
"env": {
"shared-node-browser": true
},
"rules": {
"max-lines-per-function": "off",
"no-extend-native": "off"
}
},
"prettier": {
"printWidth": 100,
"tabWidth": 4,
"overrides": [
{
"files": [
"*.md"
],
"options": {
"tabWidth": 2
}
}
]
},
"scripts": {
"lint": "eslint --ignore-path=.gitignore .",
"lint-updated": "pipe-git-updated --ext=js -- eslint --ignore-pattern '!*'",
"prettier-check-updated": "pipe-git-updated --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier -c",
"prettify": "prettier --write --ignore-path .gitignore '**/*.{css,html,js,json,md,yaml,yml}'",
"test": "node ./node_modules/tad/bin/tad"
},
"license": "ISC"
}
deferred-0.7.11/profiler.js 0000664 0000000 0000000 00000004461 13500662733 0015552 0 ustar 00root root 0000000 0000000 "use strict";
var partial = require("es5-ext/function/#/partial")
, forEach = require("es5-ext/object/for-each")
, pad = require("es5-ext/string/#/pad")
, deferred = require("./deferred");
var resolved, rStats, unresolved, uStats, profile;
exports.profile = function () {
resolved = 0;
rStats = {};
unresolved = 0;
uStats = {};
deferred._profile = profile;
};
profile = function (isResolved) {
var stack, data;
if (isResolved) {
++resolved;
data = rStats;
} else {
++unresolved;
data = uStats;
}
stack = new Error().stack;
if (
!stack.split("\n").slice(3).some(function (line) {
if (
line.search(/[/\\]deferred[/\\]/) === -1 &&
line.search(/[/\\]es5-ext[/\\]/) === -1 &&
line.indexOf(" (native)") === -1
) {
line = line.replace(/\n/g, "\\n").trim();
if (!data[line]) {
data[line] = { count: 0 };
}
++data[line].count;
return true;
}
return false;
})
) {
if (!data.unknown) {
data.unknown = { count: 0, stack: stack };
}
++data.unknown.count;
}
};
exports.profileEnd = function () {
var total, lpad, log = "";
if (!deferred._profile) {
throw new Error("Deferred profiler was not initialized");
}
delete deferred._profile;
log += "------------------------------------------------------------\n";
log += "Deferred usage statistics:\n\n";
total = String(resolved + unresolved);
lpad = partial.call(pad, " ", total.length);
log += total + " Total promises initialized\n";
log += lpad.call(unresolved) + " Initialized as Unresolved\n";
log += lpad.call(resolved) + " Initialized as Resolved\n";
if (unresolved) {
log += "\nUnresolved promises were initialized at:\n";
forEach(
uStats,
function (data, name) { log += lpad.call(data.count) + " " + name + "\n"; },
null,
function (data1, data2) { return this[data2].count - this[data1].count; }
);
}
if (resolved) {
log += "\nResolved promises were initialized at:\n";
forEach(
rStats,
function (data, name) { log += lpad.call(data.count) + " " + name + "\n"; },
null,
function (data1, data2) { return this[data2].count - this[data1].count; }
);
}
log += "------------------------------------------------------------\n";
return {
log: log,
resolved: { count: resolved, stats: rStats },
unresolved: { count: unresolved, stats: uStats }
};
};
deferred-0.7.11/test/ 0000775 0000000 0000000 00000000000 13500662733 0014344 5 ustar 00root root 0000000 0000000 deferred-0.7.11/test/.eslintrc.json 0000664 0000000 0000000 00000000157 13500662733 0017143 0 ustar 00root root 0000000 0000000 {
"rules": { "id-length": "off", "no-empty-function": "off", "no-shadow": "off" },
"env": { "node": true }
}
deferred-0.7.11/test/.lint 0000664 0000000 0000000 00000000021 13500662733 0015304 0 ustar 00root root 0000000 0000000 predef+ __dirname deferred-0.7.11/test/_ext.js 0000664 0000000 0000000 00000005575 13500662733 0015655 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../deferred");
var x = {}, y = {}, e = new Error("Error");
module.exports = {
"Then callback run in current tick": function (a) {
var next = false;
deferred(null)(function () { a(next, false); }, a.never).done();
next = true;
},
"Reject": function (a, d) {
deferred(e)(a.never, function (res) { a(res, e); }).done(d, d);
},
"Erroneous callback rejects promise": function (a, d) {
deferred(1)(function () { throw e; })(a.never, function (res) { a(res, e); }).done(d, d);
},
"Object promise resolves to same object": function (a, d) {
deferred(x)(function (result) { a(result, x); }, a.never).done(d, d);
},
"Promise returns promise": function (a) {
var p = deferred({});
a(deferred(p), p);
},
"ValueOf": function (a) {
var def = deferred(), y = def.promise;
a(y.valueOf(), y, "Unresolved");
def.resolve(x);
a(y.valueOf(), x, "Resolved");
},
"Then": {
"Callback": function (a, d) {
deferred(x)(function (result) { a(result, x); }, a.never).done(d, d);
},
"Null": function (a, d) {
deferred(x)(null, a.never)(function (result) { a(result, x); }, a.never).done(d, d);
},
"Other value": function (a, d) {
deferred(x)(y, a.never)(function (result) { a(result, y); }, a.never).done(d, d);
},
"Error": function (a, d) {
deferred(e)(a.never, function (result) { a(result, e); }).done(d, d);
},
"Chain promise & resolve with function": function (a) {
var d1, fn, p1;
d1 = deferred();
fn = function () { return "bar"; };
d1.promise(deferred("foo")).done(function (res) { a(res, "foo", "Unresolved"); });
d1.resolve(fn);
p1 = deferred(2);
a(deferred(1)(p1), p1, "Resolved");
}
},
"Done": {
"No args": {
Success: function (a) { a(deferred(null).done(), undefined); },
Error: function (a) {
a.throws(function () { deferred(e).done(); });
}
},
"Args": {
"Success": function (a) {
deferred(x).done(function (res) { a(res, x, "Result"); }, a.never);
},
"Error": function (a) {
deferred(e).done(a.never, function (err) { a(err, e, "Error"); });
},
"Success #2": function (a) {
deferred(x).done(function (res) { a(res, x, "Result"); }, null);
},
"Error: Throw": function (a) {
a.throws(function () { deferred(e).done(a.never, null); });
}
}
},
"End": {
"No args": {
Success: function (a) { a(deferred(null).done(), undefined); },
Error: function (a) {
a.throws(function () { deferred(e).done(); });
}
},
"Args": {
"Success": function (a) {
deferred(x).done(function (res) { a(res, x, "Result"); }, a.never);
},
"Error": function (a) {
deferred(e).done(a.never, function (err) { a(err, e, "Error"); });
},
"Success #2": function (a) {
deferred(x).done(function (res) { a(res, x, "Result"); }, null);
},
"Error: Throw": function (a) {
a.throws(function () { deferred(e).done(a.never, null); });
}
}
}
};
deferred-0.7.11/test/assimilate.js 0000664 0000000 0000000 00000001742 13500662733 0017041 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../deferred");
var x = {};
module.exports = {
"then": {
Resolve: function (t, a, d) {
t({ then: function (resolve) { resolve(x); } }).done(function (value) {
a(value, x);
d();
}, a.never);
},
Reject: function (t, a, d) {
t({ then: function (resolve, reject) { reject(x); } }).done(a.never, function (value) {
a(value, x);
d();
});
}
},
"done": {
Resolve: function (t, a) {
t({ then: function () {}, done: function (resolve) { resolve(x); } }).done(function (
value
) { a(value, x); }, a.never);
},
Reject: function (t, a) {
t({ then: function () {}, done: function (resolve, reject) { reject(x); } }).done(
a.never,
function (value) { a(value, x); }
);
}
},
"via then": function (t, a, d) {
deferred("marko")
.then(function () {
return { then: function (resolve) { resolve("foreign"); } };
})
.done(function (value) {
a(value, "foreign");
d();
});
}
};
deferred-0.7.11/test/deferred.js 0000664 0000000 0000000 00000007137 13500662733 0016472 0 ustar 00root root 0000000 0000000 "use strict";
var isPromise = require("../is-promise");
var x = {};
module.exports = {
"No arguments": function (t, a, d) {
var defer = t();
a(isPromise(defer.promise), true, "Promise");
defer.resolve(x)(function (res) {
a(res, x, "Resolve");
d();
});
},
"One argument": function (t, a, d) {
var p = t(x);
a(isPromise(p), true, "Got promise");
p(function (res) {
a(res, x, "Promise for passed value");
d();
});
},
"More than one argument": function (t) {
var x = {}, y = {};
return {
"Success": function (a, d) {
t(t(x), y, null)(function (r) {
a.deep(r, [x, y, null]);
d();
}).done();
},
"Error": function (a, d) {
var d1 = t(), v, res = false;
setTimeout(d1.resolve, 20);
t(
t(x),
d1.promise(function () {
a(res, true, "Resolved");
d();
}),
t.reject((v = new Error("Error"))),
{}
)(a.never, function (e) {
a(e, v);
res = true;
}).done();
},
"Resolve not via then": function (a) {
var d = t();
t(1, d.promise).done(function () { throw new Error("ERROR"); });
a.throws(d.resolve);
}
};
},
"Only first resolve is taken": function (t, a) {
var defer = t();
defer.promise.done();
defer.resolve(1);
defer.resolve(2);
a(defer.promise.valueOf(), 1);
},
"Nested Promises": function (t, a) {
var d1 = t(), d2 = t(), d3 = t(), d4 = t(), x = {};
d1.resolve(d2.promise);
d2.resolve(d3.promise);
d3.resolve(d4.promise);
d4.resolve(x);
a(d1.promise.resolved, true, "#1 resolved");
a(d2.promise.resolved, true, "#2 resolved");
a(d3.promise.resolved, true, "#3 resolved");
a(d4.promise.resolved, true, "#4 resolved");
d1.promise(function (arg) { a(arg, x, "#1"); }).done();
d2.promise(function (arg) { a(arg, x, "#2"); }).done();
d3.promise(function (arg) { a(arg, x, "#3"); }).done();
d2.promise(function (arg) { a(arg, x, "#4"); }).done();
},
"Transfer pending": function (t, a) {
var d1 = t(), d2 = t(), x = {}, p;
d1.resolve(d2.promise);
p = d1.promise(function (arg) { return [arg, "foo"]; });
d2.resolve(x);
a(p.resolved, true, "Transfered");
a.deep(p.value, [x, "foo"], "Transfered value");
},
"Resolve corner case": function (t, a) {
var d1 = t(), d2 = t(), d3 = t(), d4 = t(), count = 0;
d1.promise(function () { ++count; });
d2.promise(function () { ++count; });
d3.promise(function () { ++count; });
d4.promise(function () { ++count; });
d1.resolve(d2.promise);
d2.resolve(d3.promise);
d3.resolve(d4.promise);
d2.promise(function () { ++count; });
d1.promise(function () { ++count; });
d4.resolve({});
a(count, 6);
},
"Call all then callbacks in order": function (t, a, d) {
var def = t(), promise = def.promise, x = {}, count = 0;
promise(function () { ++count; }, a.never).done();
promise(function () { a(count, 1); }, a.never).done(d, d);
def.resolve(x);
},
"Resolve promise with other promise": function (t, a, d) {
var def1 = t(), p1 = def1.promise, x = {}, def2 = t(), p2 = def2.promise;
p1(function (result) { a(result, x); }, a.never).done(d, d);
def1.resolve(p2);
def2.resolve(x);
},
"Reject": function (t, a) {
var e = new Error("Error!");
t().reject(e).done(a.never, function (result) { a(result, e); });
},
"Reject function": function (t, a) {
var rejected = t.reject("elo");
a(isPromise(rejected), true, "Promise");
a(rejected.failed, true, "Rejected");
a(rejected.value, "elo", "value");
},
"Resolve function": function (t, a) {
var resolved = t.resolve("elo");
a(isPromise(resolved), true, "Promise");
a(resolved.failed, false, "Resolveed");
a(resolved.value, "elo", "value");
}
};
deferred-0.7.11/test/dynamic-queue.js 0000664 0000000 0000000 00000003441 13500662733 0017452 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../deferred");
var reject = deferred.reject;
module.exports = function (T) {
var x = {}, y = {}, z = {}, e = new Error("Error");
return {
"Empty": function (a, d) {
new T([]).promise(function (result) { a.deep(result, undefined); }, a.never).done(d, d);
},
"One": {
Value: function (a, d) {
new T([x])
.promise(function (result) { a.deep(result, undefined); }, a.never)
.done(d, d);
},
Promise: function (a, d) {
new T([deferred(x)])
.promise(function (result) { a.deep(result, undefined); }, a.never)
.done(d, d);
}
},
"Many": {
"Error": function (a, d) {
new T([x, y, deferred(x), reject(e), z]).promise(a.never, function (res) {
a(res, e);
d();
});
},
"Values & Promises": function (a, d) {
new T([x, y, deferred(x), z, deferred(y)])
.promise(function (res) { a.deep(res, undefined); }, a.never)
.done(d, d);
},
"Postponed": function (a, d) {
var def = deferred(), resolved = false;
new T([x, y, deferred(x), def.promise, z, deferred(y)])
.promise(function (res) { a.deep(res, undefined); }, a.never)
.done(d, d);
a(resolved, false);
def.resolve();
},
"Error promise": function (a, d) {
new T([x, y, deferred(e), z, deferred(y)])
.promise(a.never, function (res) { a(res, e); }, a.never)
.done(d, d);
}
},
"Resolve not via then": function (a) {
// With v0.3.0 we introduced a bug - resolve of map in some cases was
// called within callback passed to then, therefore any following errors
// in given event loop were silent - this test makes sure it's not the
// case anymore
var d = deferred();
new T([d.promise]).promise.done(function () { throw new Error("ERROR"); });
a.throws(d.resolve);
}
};
};
deferred-0.7.11/test/ext/ 0000775 0000000 0000000 00000000000 13500662733 0015144 5 ustar 00root root 0000000 0000000 deferred-0.7.11/test/ext/_process-arguments.js 0000664 0000000 0000000 00000002237 13500662733 0021326 0 ustar 00root root 0000000 0000000 "use strict";
var isPromise = require("../../is-promise")
, deferred = require("../../deferred");
module.exports = function (t) {
var x = {}, y = {}, e = new Error();
return {
"Limit": function (a) { a.deep(t([x, 34, "raz"], 2), [x, 34]); },
"Extend": function (a) {
a.deep(t([x, 34, "raz"], 5), [x, 34, "raz", undefined, undefined]);
},
"Promise arguments": {
Resolved: {
"": function (a) {
a.deep(t([x, deferred(y), "dwa", deferred(null)]), [x, y, "dwa", null]);
},
"Error": function (a) {
var p = deferred(e);
a(t([x, p, "dwa", deferred(null)]), p);
}
},
Unresolved: {
"": function (a) {
var py = deferred(), px = deferred(), p;
p = t([x, py.promise, "dwa", px.promise]);
a(isPromise(p), true, "Promise");
p.done(function (args) { a.deep(args, [x, y, "dwa", x]); }, a.never);
py.resolve(y);
px.resolve(x);
},
"Error": function (a) {
var py = deferred(), px = deferred(), p;
p = t([x, py.promise, "dwa", px.promise]);
a(isPromise(p), true, "Promise");
p.done(a.never, function (err) { a(err, e); });
py.resolve(y);
px.reject(e);
}
}
}
};
};
deferred-0.7.11/test/ext/array/ 0000775 0000000 0000000 00000000000 13500662733 0016262 5 ustar 00root root 0000000 0000000 deferred-0.7.11/test/ext/array/every.js 0000664 0000000 0000000 00000003465 13500662733 0017762 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred")
, isPromise = require("../../../is-promise");
module.exports = function (t, a) {
var x = {}, y, z = 0, w;
a(t.call([]).valueOf(), true, "Empty, no cb");
a(t.call([], function () { return true; }).valueOf(), true, "Empty, cb");
a(t.call([{}]).valueOf(), true, "One, truthy, no cb");
a(t.call([0]).valueOf(), false, "One, falsy, no cb");
a(t.call([0, {}]).valueOf(), false, "Two, falsy & truthy, no cb");
a(t.call([0, false]).valueOf(), false, "Two, falsy & falsy, no cb");
a(
t
.call(
(y = [false]),
function (a1, a2, a3) {
++z;
a(a1, false, "Argument");
a(a2, 0, "Index");
a(a3, y, "List");
a(this, x, "Context");
return true;
},
x
)
.valueOf(),
true,
"One, falsy, cb truthy"
);
a(z, 1, "Callback called");
a(t.call([1], function () { return false; }).valueOf(), false, "One, truthy, cb falsy");
a(
t
.call([1, 0], function (x) {
++z;
return !x;
})
.valueOf(),
false,
"Two, cb, Second truthy"
);
a(z, 2, "Callback called once");
y = deferred();
w = t.call([y.promise, 3, 4]);
a(isPromise(w.valueOf()), true, "In order");
y.resolve(0);
a(w.valueOf(), false, "In order, resolved");
y = deferred();
z = [];
w = t.call([y.promise, 3, 4], function (val) {
z.push(val);
return Boolean(val);
});
a(isPromise(w.valueOf()), true, "In order, cb");
y.resolve(1);
a(w.valueOf(), true, "In order, cb, resolved");
a.deep(z, [1, 3, 4], "In order, cb, called");
y = deferred();
z = [];
w = t.call([0, 3, 4], function (val) {
z.push(val);
return y.promise;
});
a(isPromise(w.valueOf()), true, "Promise cb");
a.deep(z, [0], "Promise cb, processed one");
y.resolve(0);
a(w.valueOf(), false, "Promise cb, resolved");
a.deep(z, [0], "Promise cb, processed, resolved");
};
deferred-0.7.11/test/ext/array/find.js 0000664 0000000 0000000 00000003462 13500662733 0017545 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred")
, isPromise = require("../../../is-promise");
module.exports = function (t, a) {
var x = {}, y, z = 0, w;
a(t.call([]).valueOf(), undefined, "Empty, no cb");
a(t.call([], function () { return true; }).valueOf(), undefined, "Empty, cb");
a(t.call([x]).valueOf(), x, "One, truthy, no cb");
a(t.call([0]).valueOf(), undefined, "One, falsy, no cb");
a(t.call([0, x]).valueOf(), x, "Two, falsy & truthy, no cb");
a(t.call([0, false]).valueOf(), undefined, "Two, falsy & falsy, no cb");
a(
t
.call(
(y = [false]),
function (a1, a2, a3) {
++z;
a(a1, false, "Argument");
a(a2, 0, "Index");
a(a3, y, "List");
a(this, x, "Context");
return true;
},
x
)
.valueOf(),
false,
"One, falsy, cb truthy"
);
a(z, 1, "Callback called");
a(t.call([1], function () { return false; }).valueOf(), undefined, "One, truthy, cb falsy");
a(
t
.call([1, 0], function (x) {
++z;
return !x;
})
.valueOf(),
0,
"Two, cb, Second truthy"
);
a(z, 3, "Callback called twice");
y = deferred();
w = t.call([y.promise, 3, 4]);
a(isPromise(w.valueOf()), true, "In order");
y.resolve(0);
a(w.valueOf(), 3, "In order, resolved");
y = deferred();
z = [];
w = t.call([y.promise, 3, 4], function (val) {
z.push(val);
return Boolean(val);
});
a(isPromise(w.valueOf()), true, "In order, cb");
y.resolve(0);
a(w.valueOf(), 3, "In order, cb, resolved");
a.deep(z, [0, 3], "In order, cb, called");
y = deferred();
z = [];
w = t.call([0, 3, 4], function (val) {
z.push(val);
return y.promise;
});
a(isPromise(w.valueOf()), true, "Promise cb");
a.deep(z, [0], "Promise cb, processed one");
y.resolve(3);
a(w.valueOf(), 0, "Promise cb, resolved");
a.deep(z, [0], "Promise cb, processed, resolved");
};
deferred-0.7.11/test/ext/array/map.js 0000664 0000000 0000000 00000006434 13500662733 0017404 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred")
, reject = deferred.reject;
module.exports = function (t) {
var x = {}, y = {}, z = {}, e = new Error("Error");
return {
"Empty": {
"": function (a, d) {
t.call([])(function (result) { a.deep(result, []); }, a.never).done(d, d);
},
"Callback": function (a, d) {
t.call([], a.never)(function (result) { a.deep(result, []); }, a.never).done(d, d);
}
},
"One": {
Value: {
"": function (a, d) {
t.call([x])(function (result) { a.deep(result, [x]); }, a.never).done(d, d);
},
"Callback": function (a, d) {
var list = [x];
t.call(
list,
function (arg, index, target) {
a(arg, x, "Argument");
a(index, 0, "Index");
a(target, list, "Target");
a(this, x, "Context");
return y;
},
x
)(function (result) { a.deep(result, [y]); }, a.never).done(d, d);
}
},
Promise: {
"": function (a, d) {
t.call([deferred(x)])(function (result) { a.deep(result, [x]); }, a.never).done(
d, d
);
},
"Callback": function (a, d) {
t.call([deferred(x)], function (arg) {
a(arg, x, "Argument");
return y;
})(function (result) { a.deep(result, [y]); }, a.never).done(d, d);
}
}
},
"Many": {
"No callback": {
"Error": function (a, d) {
t.call([x, y, deferred(x), reject(e), z])(a.never, function (res) {
a(res, e);
d();
});
},
"Values & Promises": function (a, d) {
t.call([x, y, deferred(x), z, deferred(y)])(function (res) {
a.deep(res, [x, y, x, z, y]);
}, a.never).done(d, d);
},
"Error promise": function (a, d) {
t.call([x, y, deferred(e), z, deferred(y)])(
a.never, function (res) { a(res, e); }, a.never
).done(d, d);
}
},
"Callback": {
"Error": function (a, d) {
var count = 0;
t.call([x, y, deferred(x), z], function () {
if (count++) {
a.never();
}
throw e;
})(a.never, function (res) { a(res, e); }).done(d, d);
},
"Error via input": function (a, d) {
t.call([x, y, deferred(e), z], function () { return x; })(a.never, function (
res
) { a(res, e); }).done(d, d);
},
"Values & Promises": function (a, d) {
t.call([1, deferred(2), 3, deferred(4), 5], function (val) {
return val * val;
})(function (res) { a.deep(res, [1, 4, 9, 16, 25]); }, a.never).done(d, d);
},
"Values & Promises, through promise": function (a, d) {
t.call([1, deferred(2), 3, deferred(4), 5], function (val) {
return deferred(val * val);
})(function (res) { a.deep(res, [1, 4, 9, 16, 25]); }, a.never).done(d, d);
}
}
},
"Resolve not via then": function (a) {
// With v0.3.0 we introduced a bug - resolve of map in some cases was
// called within callback passed to then, therefore any following errors
// in given event loop were silent - this test makes sure it's not the
// case anymore
var d = deferred();
t.call([d.promise]).done(function () { throw new Error("ERROR"); });
a.throws(d.resolve);
},
"Return rejected promise in callback": function (a) {
var e = new Error("Some error");
t.call([1, 2], function () { return reject(e); }).done(a.never, function (err) {
a(err, e);
});
}
};
};
deferred-0.7.11/test/ext/array/reduce.js 0000664 0000000 0000000 00000015111 13500662733 0020066 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred")
, reject = deferred.reject;
module.exports = function (t) {
var x = {}, y = {}, z = {}, e = new Error("Error"), e2 = new Error("Error2");
return {
Empty: {
"No initial": function (a) {
a.throws(function () { t.call([]); });
a.throws(function () {
t.call([], function () { return x; });
});
},
"Initial": {
"": function (a, d) {
t.call([], null, x)(function (res) { a(res, x); }, a.never).done(d, d);
},
"Undefined": function (a, d) {
t.call([], null, undefined)(function (res) {
a(res, undefined);
}, a.never).done(d, d);
},
"Callback": function (a, d) {
t.call([], a.never, x)(function (res) { a(res, x); }, a.never).done(d, d);
},
"Promise": function (a, d) {
t.call([], a.never, deferred(y))(function (res) { a(res, y); }, a.never).done(
d, d
);
},
"Error": function (a, d) {
t.call([], a.never, reject(e))(a.never, function (res) { a(res, e); }).done(
d, d
);
}
}
},
One: {
"No initial": {
Regular: {
"": function (a, d) {
t.call([x])(function (res) { a(res, x); }, a.never).done(d, d);
},
"Callback": {
"": function (a, d) {
var list = [x];
t.call(list, a.never)(function (res) { a(res, x); }, a.never).done(
d, d
);
},
"Promise": function (a, d) {
t.call([x], a.never)(function (res) { a(res, x); }, a.never).done(d, d);
},
"Throw Error": function (a, d) {
t.call([x], function () { throw e; }, null)(a.never, function (res) {
a(res, e);
}).done(d, d);
},
"Return Error": function (a, d) {
t.call([deferred(e)], function () { return e; }, null)(
a.never,
function (res) { a(res, e); }
).done(d, d);
}
}
},
Promise: {
"": function (a, d) {
t.call([deferred(x)])(function (res) { a(res, x); }, a.never).done(d, d);
},
"Callback": function (a, d) {
t.call(
[deferred(x)],
function (acc, arg) {
a(acc, null, "Accumulator");
a(arg, x, "Argument");
return y;
},
null
)(function (res) { a(res, y); }, a.never).done(d, d);
}
},
Undefined: function (a, d) {
t.call([undefined])(function (res) { a(res, undefined); }, a.never).done(d, d);
},
Error: {
"": function (a, d) {
t.call([reject(e)])(a.never, function (res) { a(res, e); }, a.never).done(
d, d
);
},
"Promise": function (a, d) {
t.call([deferred(e)])(a.never, function (res) { a(res, e); }, a.never).done(
d, d
);
},
"Callback": {
"": function (a, d) {
t.call(
[e],
function (acc, arg) {
a(acc, null, "Accumulator");
a(arg, e, "Argument");
return y;
},
null
)(function (res) { a(res, y); }, a.never).done(d, d);
},
"Promise": function (a, d) {
t.call([deferred(e)], a.never)(a.never, function (res) {
a(res, e);
}).done(d, d);
},
"Throw Error": function (a, d) {
var e2 = new Error("Error");
t.call(
[e],
function (acc, arg) {
a(arg, e, "Argument");
throw e2;
},
null
)(a.never, function (res) { a(res, e2); }).done(d, d);
},
"Return Error": function (a, d) {
var e2 = new Error("Error");
t.call(
[e],
function (acc, arg) {
a(arg, e, "Argument");
return e2;
},
null
)(function (res) { a(res, e2); }, a.never).done(d, d);
}
}
}
},
"Initial": {
Regular: {
"": function (a, d) {
t.call([x], null, y)(function (res) { a(res, x); }, a.never).done(d, d);
},
"Initial Error": function (a, d) {
t.call(
[x],
function (err) {
a(err, e, "Call");
throw e;
},
e
)(a.never, function (res) { a(res, e); }).done(d, d);
},
"Callback": {
"": function (a, d) {
t.call(
[x],
function (acc, arg) {
a(acc, z, "Accumulator");
a(arg, x, "Argument");
return y;
},
z
)(function (res) { a(res, y); }, a.never).done(d, d);
}
}
},
Promise: {
"": function (a, d) {
t.call([deferred(x)], null, deferred(y))(function (res) {
a(res, x);
}, a.never).done(d, d);
},
"Callback": function (a, d) {
t.call(
[deferred(x)],
function (acc, arg) {
a(acc, z, "Accumulator");
a(arg, x, "Argument");
return deferred(y);
},
deferred(z)
)(function (res) { a(res, y); }, a.never).done(d, d);
}
},
Undefined: function (a, d) {
t.call([undefined], null, z)(function (res) {
a(res, undefined);
}, a.never).done(d, d);
}
}
},
Many: {
"Initial error": function (a, d) {
var list = [x, y, z];
t.call(
list,
function (a1, a2, a3, a4) {
a.deep([a1, a2, a3, a4], [e, x, 0, list]);
return e;
},
reject(e)
)(a.never, function (res) { a(res, e); }).done(d, d);
},
"No callback": {
"Error": function (a, d) {
t.call([x, reject(e), e2])(a.never, function (res) { a(res, e); }).done(d, d);
},
"Error promise": function (a, d) {
t.call([x, deferred(e), e2])(a.never, function (res) { a(res, e); }).done(d, d);
},
"Values": function (a, d) {
t.call([x, y, z])(function (res) { a(res, z); }, a.never).done(d, d);
},
"Values & Promises": function (a, d) {
t.call([x, deferred(y), z])(function (res) { a(res, z); }, a.never).done(d, d);
},
"Values & Promises & Initial": function (a, d) {
t.call([x, deferred(y), z], null, {})(function (res) {
a(res, z);
}, a.never).done(d, d);
}
},
"Callback": {
"Error": function (a, d) {
t.call([x, e, e2], function () { return z; })(function (res) {
a(res, z);
}, a.never).done(d, d);
},
"Error promise": function (a, d) {
t.call([x, deferred(e), e2], function () { return z; })(a.never, function (
res
) { a(res, e); }).done(d, d);
},
"Values": function (a, d) {
t.call([1, 2, 3], function (acc, res) { return acc * res; }, 1)(function (res) {
a(res, 6);
}, a.never).done(d, d);
},
"Values & Promises": function (a, d) {
t.call(
[1, deferred(2), 3], function (acc, res) { return deferred(acc * res); },
deferred(1)
)(function (res) { a(res, 6); }, a.never).done(d, d);
}
}
}
};
};
deferred-0.7.11/test/ext/array/some.js 0000664 0000000 0000000 00000003461 13500662733 0017567 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred")
, isPromise = require("../../../is-promise");
module.exports = function (t, a) {
var x = {}, y, z = 0, w;
a(t.call([]).valueOf(), false, "Empty, no cb");
a(t.call([], function () { return true; }).valueOf(), false, "Empty, cb");
a(t.call([{}]).valueOf(), true, "One, truthy, no cb");
a(t.call([0]).valueOf(), false, "One, falsy, no cb");
a(t.call([0, {}]).valueOf(), true, "Two, falsy & truthy, no cb");
a(t.call([0, false]).valueOf(), false, "Two, falsy & falsy, no cb");
a(
t
.call(
(y = [false]),
function (a1, a2, a3) {
++z;
a(a1, false, "Argument");
a(a2, 0, "Index");
a(a3, y, "List");
a(this, x, "Context");
return true;
},
x
)
.valueOf(),
true,
"One, falsy, cb truthy"
);
a(z, 1, "Callback called");
a(t.call([1], function () { return false; }).valueOf(), false, "One, truthy, cb falsy");
a(
t
.call([1, 0], function (x) {
++z;
return !x;
})
.valueOf(),
true,
"Two, cb, Second truthy"
);
a(z, 3, "Callback called twice");
y = deferred();
w = t.call([y.promise, 3, 4]);
a(isPromise(w.valueOf()), true, "In order");
y.resolve(0);
a(w.valueOf(), true, "In order, resolved");
y = deferred();
z = [];
w = t.call([y.promise, 3, 4], function (val) {
z.push(val);
return Boolean(val);
});
a(isPromise(w.valueOf()), true, "In order, cb");
y.resolve(0);
a(w.valueOf(), true, "In order, cb, resolved");
a.deep(z, [0, 3], "In order, cb, called");
y = deferred();
z = [];
w = t.call([0, 3, 4], function (val) {
z.push(val);
return y.promise;
});
a(isPromise(w.valueOf()), true, "Promise cb");
a.deep(z, [0], "Promise cb, processed one");
y.resolve(3);
a(w.valueOf(), true, "Promise cb, resolved");
a.deep(z, [0], "Promise cb, processed, resolved");
};
deferred-0.7.11/test/ext/function/ 0000775 0000000 0000000 00000000000 13500662733 0016771 5 ustar 00root root 0000000 0000000 deferred-0.7.11/test/ext/function/call-async.js 0000664 0000000 0000000 00000003361 13500662733 0021360 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t) {
var u = {}, x = {}, y = {}, z = {};
return {
"Promise arguments": function (a, d) {
t.call(
function (arg1, arg2, callback) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
},
u,
x,
deferred(y)
)(function (result) { a(result, z); }, a.never).done(d, d);
},
"Normal arguments": function (a, d) {
t.call(
function (arg1, arg2, callback) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, undefined], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
},
u,
x,
undefined
)(function (result) { a(result, z); }, a.never).done(d, d);
},
"Successful": function (a, d) {
var x = {}, y = {}, z = {};
t.call(
function (arg1, arg2, callback) {
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
},
null,
x,
y
)(function (result) { a(result, z, "Result"); }, a.never).done(d, d);
},
"Successful: Many args": function (a, d) {
var x = {}, y = {}, z = {};
t.call(
function (arg1, arg2, callback) {
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, x, y, z); }, 0);
},
null,
x,
y
)(function (result) { a.deep(result, [x, y, z], "Result"); }, a.never).done(d, d);
},
"Erroneous": function (a, d) {
var x = new Error("Test");
t.call(function (callback) {
setTimeout(function () { callback(x); }, 0);
})(a.never, function (e) { a(e, x); }).done(d, d);
},
"Function crash": function (a) {
a.throws(t.bind(function () { throw x; }));
}
};
};
deferred-0.7.11/test/ext/function/delay.js 0000664 0000000 0000000 00000000647 13500662733 0020434 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = function (t, a, d) {
var x = {}, y = {}, z = {}, p, r;
t.call(function (arg1, arg2) { return [this, arg1, arg2]; }, 100)
.call(x, y, z)(function (arg) {
p = y;
r = arg;
})
.done();
a.not(p, y, "Not yet");
setTimeout(function () {
a.not(p, y, "After a while");
setTimeout(function () {
a(p, y, "Timed");
a.deep(r, [x, y, z], "Result");
d();
}, 70);
}, 50);
};
deferred-0.7.11/test/ext/function/gate.js 0000664 0000000 0000000 00000005742 13500662733 0020257 0 ustar 00root root 0000000 0000000 "use strict";
var aFrom = require("es5-ext/array/from")
, deferred = require("../../../deferred");
module.exports = function (t) {
var fn, gfn, x = {}, y = {}, z = {}, args, dx, dy, dz, hz, resolved, released;
fn = function (p) {
args = aFrom(arguments);
return p;
};
return {
"Limit": function (a) {
var invoked, x = {};
gfn = t.call(fn, 2);
dx = deferred();
a(gfn(dx.promise, "x"), dx.promise, "#1"); // X
dy = deferred();
a(gfn(dy.promise, "y"), dy.promise, "#2"); // Y
dz = deferred();
a.not((hz = gfn(dz.promise, "z")), dz.promise, "#3 blocked");
hz.on("test", function (arg) { invoked = arg; });
hz.done(function (r) {
released = true;
a(r, z, "Held resolution");
a(resolved, true, "Held timing");
});
gfn(x, y, z);
dz.resolve(z);
resolved = true;
dy.resolve(y); // Z, 4
dz.promise.emit("test", x);
a(invoked, x, "Events unified");
a(released, true, "Released");
resolved = false;
dx.resolve(x);
a.deep(args, [x, y, z], "Held Arguments");
},
"No args": function (a) {
gfn = t.call(fn);
dx = deferred();
a(gfn(dx.promise), dx.promise, "#1");
dz = deferred();
a.not((hz = gfn(dz.promise)), dz.promise, "#2 blocked");
hz.done(function (r) {
a(r, z, "Held resolution");
a(resolved, true, "Held timing");
});
dz.resolve(z);
resolved = true;
dx.resolve(x);
resolved = false;
},
"Queue limit 0": function (a) {
gfn = t.call(fn, 2, 0);
dx = deferred();
a(gfn(dx.promise), dx.promise, "#1");
dy = deferred();
a(gfn(dy.promise), dy.promise, "#2");
gfn(x).done(null, function (err) {
a(err.type, "deferred-gate-rejected", "Reject error");
});
dy.resolve(y);
dz = deferred();
a(gfn(dz.promise), dz.promise, "#3");
gfn(x).done(null, function (err) {
a(err.type, "deferred-gate-rejected", "Reject error");
});
dx.resolve(x);
dz.resolve(z);
},
"Queue limit 2": function (a) {
gfn = t.call(fn, 2, 1);
// X
dx = deferred();
a(gfn(dx.promise), dx.promise, "#1");
// X, y
dy = deferred();
a(gfn(dy.promise), dy.promise, "#2");
// X, y, z
dz = deferred();
a.not((hz = gfn(dz.promise)), dz.promise, "#3 blocked");
hz.done(function (r) { a(r, z, "#3 held"); });
// X, y, z
gfn(x).done(null, function (err) {
a(err.type, "deferred-gate-rejected", "Reject error");
});
dz.resolve(z);
dy.resolve(y);
// X
// x, y
dy = deferred();
a(gfn(dy.promise), dy.promise, "#2");
// X, y, z
dz = deferred();
a.not((hz = gfn(dz.promise)), dz.promise, "#3 blocked");
hz.done(function (r) { a(r, z, "#3 held"); });
// X, y, z
gfn(x).done(null, function (err) {
a(err.type, "deferred-gate-rejected", "Reject error");
});
dz.resolve(z);
dy.resolve(y);
dx.resolve(x);
},
"Resolution type": function (a) {
var error = new Error("Test");
gfn = t.call(function () { return deferred.reject(error); }, 1, 0);
gfn().done(a.never, function (err) { a(err, error); });
}
};
};
deferred-0.7.11/test/ext/function/promisify-sync.js 0000664 0000000 0000000 00000001436 13500662733 0022326 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t) {
var u = {}, x = {}, y = {}, z = {};
return {
"Promise arguments": function (a) {
t.call(function (arg1, arg2) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, y], "Arguments");
return z;
}, 2)
.call(u, x, deferred(y), z)
.done(function (result) { a(result, z); });
},
"Normal arguments": function (a) {
t.call(function (arg1, arg2) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, undefined], "Arguments");
return z;
}, 2)
.call(u, x)
.done(function (result) { a(result, z); });
},
"Error": function (a) {
var e = new Error("Error");
t.call(function () { throw e; })().done(a.never, function (result) { a(result, e); });
}
};
};
deferred-0.7.11/test/ext/function/promisify.js 0000664 0000000 0000000 00000003602 13500662733 0021351 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t) {
var u = {}, x = {}, y = {}, z = {};
return {
"Promise arguments": function (a, d) {
t.call(function (arg1, arg2, callback) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
}, 2)
.call(u, x, deferred(y), z)(function (result) { a(result, z); }, a.never)
.done(d, d);
},
"Normal arguments": function (a, d) {
t.call(function (arg1, arg2, callback) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, undefined], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
}, 2)
.call(u, x)(function (result) { a(result, z); }, a.never)
.done(d, d);
},
"Do not promisify promisified function": function (a) {
var fn, fn1;
fn = t.call(function () {});
fn1 = t.call(fn);
a(fn, fn1);
},
"Successful": function (a, d) {
var x = {}, y = {}, z = {};
t.call(function (arg1, arg2, callback) {
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
})(x, y)(function (result) { a(result, z, "Result"); }, a.never).done(d, d);
},
"Successful: Many args": function (a, d) {
var x = {}, y = {}, z = {};
t.call(function (arg1, arg2, callback) {
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, x, y, z); }, 0);
})(x, y)(function (result) { a.deep(result, [x, y, z], "Result"); }, a.never).done(
d, d
);
},
"Erroneous": function (a, d) {
var x = new Error("Test");
t.call(function (callback) {
setTimeout(function () { callback(x); }, 0);
}, 0)(y)(a.never, function (e) { a(e, x); }).done(d, d);
},
"Function crash": function (a) {
var x = new Error("Test"), fn;
fn = t.call(function () { throw x; });
a.throws(function () { fn(); });
}
};
};
deferred-0.7.11/test/ext/promise/ 0000775 0000000 0000000 00000000000 13500662733 0016622 5 ustar 00root root 0000000 0000000 deferred-0.7.11/test/ext/promise/_array.js 0000664 0000000 0000000 00000002447 13500662733 0020444 0 ustar 00root root 0000000 0000000 "use strict";
var isError = require("es5-ext/error/is-error")
, deferred = require("../../../deferred");
module.exports = function (t) {
t("map", require("../../../ext/array/map"));
return {
Direct: function (a) {
deferred([deferred(1), deferred(2), 3])
.map(function (res) { return deferred(res * res); })(function (r) {
a.deep(r, [1, 4, 9]);
}, a.never)
.done();
},
Delayed: function (a) {
var def = deferred();
def.promise
.map(function (res) { return deferred(res * res); })(function (r) {
a.deep(r, [1, 4, 9]);
}, a.never)
.done();
def.resolve([deferred(1), deferred(2), 3]);
},
OnSettledRejected: function (a) {
var error = new Error("foo");
deferred
.reject(error)
.map(function () { return "foo"; })
.done(a.never, function (reason) { a(reason, error); });
},
OnPendingRejected: function (a) {
var error = new Error("foo");
var def = deferred();
def.promise
.map(function () { return "foo"; })
.done(a.never, function (reason) { a(reason, error); });
def.reject(error);
},
Error: function (a) {
t("reduce", require("../../../ext/array/reduce"));
deferred([])
.reduce(function () { return null; })(a.never, function (err) {
a(isError(err), true, "Error");
})
.done();
}
};
};
deferred-0.7.11/test/ext/promise/aside.js 0000664 0000000 0000000 00000001646 13500662733 0020254 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t, a) {
var x = {}, d = deferred(), p = d.promise, invoked = false;
a(p.aside(), p, "Callback is optional");
a(
p.aside(function (o) {
a(o, x, "Unresolved: arguments");
invoked = true;
}, a.never),
p,
"Returns self promise"
);
a(invoked, false, "Callback not invoked on unresolved promise");
d.resolve(x);
a(invoked, true, "Callback invoked immediately on resolution");
invoked = false;
p.aside(function (o) {
a(o, x, "Resolved: arguments");
invoked = true;
}, a.never);
a(invoked, true, "Callback invoked immediately on resolved promise");
p = deferred((x = new Error("Error")));
invoked = false;
p.aside(a.never, function (err) {
a(err, x, "Erronous: arguments");
invoked = true;
});
a(invoked, true, "Called on erronous");
p.aside(a.never, null);
p = deferred((x = {}));
p.aside(null, a.never);
};
deferred-0.7.11/test/ext/promise/catch.js 0000664 0000000 0000000 00000001375 13500662733 0020250 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred")
, isPromise = require("../../../is-promise");
module.exports = function (t, a) {
var x = {}, y = {}, d = deferred(), p = d.promise, np, invoked = false, val;
a.throws(function () { p.catch(); }, "Value is mandatory");
a.not((np = p.catch(a.never)), p, "Returns other promise");
a(isPromise(np), true, "Returns promise");
d.resolve(x);
np.done(function (x) { val = x; });
a(val, x, "Pass success");
p = deferred((x = new Error("Error")));
np = p.catch(function (o) {
a(o, x, "Resolved: arguments");
invoked = true;
return y;
});
a(invoked, true, "Callback invoked immediately on resolved promise");
np.done(function (x) { val = x; });
a(val, y, "Resolves with returned value");
};
deferred-0.7.11/test/ext/promise/cb.js 0000664 0000000 0000000 00000002125 13500662733 0017544 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function () {
return {
Unresolved: function (a, d) {
var x = {}, def = deferred(), p = def.promise, invoked = false;
a(p.cb(), p, "Callback is optional");
a(
p.cb(function (err, o) {
a.deep([err, o], [null, x], "Unresolved: arguments");
invoked = true;
}),
p,
"Returns self promise"
);
a(invoked, false, "Callback not invoked on unresolved promise");
invoked = false;
def.resolve(x);
a(invoked, false, "Callback not invoked in current tick");
invoked = false;
p.cb(function (err, o) {
a.deep([err, o], [null, x], "Resolved: arguments");
invoked = true;
d();
});
a(invoked, false, "Callback not invoked immediatelly on resolved promise");
},
Errorneus: function (a, d) {
var x = new Error("Error"), p = deferred(x), invoked = false;
invoked = false;
p.cb(function (err, o) {
a.deep([err, o], [x, undefined], "Erronous: arguments");
invoked = true;
d();
});
a(invoked, false, "Called not invoked immediately");
}
};
};
deferred-0.7.11/test/ext/promise/finally.js 0000664 0000000 0000000 00000001747 13500662733 0020627 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t, a) {
var x = {}, d = deferred(), p = d.promise, invoked = false;
a(
p.finally(function (o) {
a(o, undefined, "Unresolved: arguments");
invoked = true;
}),
p,
"Returns self promise"
);
a(invoked, false, "Callback not invoked on unresolved promise");
d.resolve(x);
a(invoked, true, "Callback invoked immediately on resolution");
invoked = false;
p.finally(function (o) {
a(o, undefined, "Resolved: arguments");
invoked = true;
});
a(invoked, true, "Callback invoked immediately on resolved promise");
p = deferred();
p.promise.finally(function (o) {
a(o, undefined, "Erronous unresolved: arguments");
invoked = true;
});
invoked = false;
p = p.reject((x = new Error("Error")));
a(invoked, true, "Called on reject");
invoked = false;
p.finally(function (o) {
a(o, undefined, "Erronous: arguments");
invoked = true;
});
a(invoked, true, "Called on erronous");
};
deferred-0.7.11/test/ext/promise/get.js 0000664 0000000 0000000 00000001401 13500662733 0017733 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = {
"Deferred": function (a) {
var defer = deferred(), x = {}, y = { foo: x }, invoked = false;
defer.resolve(y).get("foo").done(function (r) {
invoked = true;
a(r, x);
});
a(invoked, true, "Resolved in current tick");
},
"Promise": function (a) {
var x = {}, y = { foo: x };
deferred(y).get("foo").done(function (r) { a(r, x); });
},
"Nested": function (a) {
var x = {}, y = { foo: { bar: x } };
deferred(y).get("foo", "bar").done(function (r) { a(r, x); });
},
"Safe for extensions": function (a) {
a.throws(function () {
var x = deferred();
x.promise.get("foo").done(function () { throw new Error("Error"); });
x.resolve({ foo: "bar" });
});
}
};
deferred-0.7.11/test/ext/promise/invoke-async.js 0000664 0000000 0000000 00000003507 13500662733 0021573 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function () {
return {
"Function": function (a, d) {
var x = {}, z = {};
z.foo = function (y, cb) {
var self = this;
setTimeout(function () { cb(null, self, y); }, 0);
return 3;
};
deferred(z).invokeAsync("foo", x)(function (r) { a.deep(r, [z, x]); }).done(d, d);
},
"Method": function (a, d) {
var x = {}, fn, z = {};
fn = function (y, cb) {
var self = this;
setTimeout(function () { cb(null, self, y); }, 0);
return 3;
};
deferred(z).invokeAsync(fn, x)(function (r) { a.deep(r, [z, x]); }).done(d, d);
},
"Fail": function (a) {
var e = new Error("Error");
deferred(e).invokeAsync("bla")(a.never, function (r) { a(r, e); }).done();
},
"Null input": function (a) {
deferred(null)
.invokeAsync("test")(a.never, function (e) { a.ok(e instanceof TypeError); })
.done();
},
"No Function": function (a) {
deferred({})
.invokeAsync("test")(a.never, function (e) { a.ok(e instanceof TypeError); })
.done();
},
"Promise arguments": function (a) {
var y = {}
, z = {}
, x = {
foo: function (w, u, cb) {
a(this, x, "Context");
a.deep([w, u], [y, z], "Arguments");
cb(null, "foo");
}
};
deferred(x)
.invokeAsync("foo", deferred(y), z)(function (r) {
a(r, "foo", "Result");
}, a.never)
.done();
},
"Erroneous": function (a, d) {
var x, fn;
x = new Error("Test");
fn = function (callback) {
setTimeout(function () { callback(x); }, 0);
};
deferred({}).invokeAsync(fn)(a.never, function (e) { a(e, x); }).done(d, d);
},
"Function crash": function (a) {
var x = new Error("Test"), fn;
fn = function () { throw x; };
deferred({}).invokeAsync(fn)(a.never, function (e) { a(e, x); }).done();
}
};
};
deferred-0.7.11/test/ext/promise/invoke.js 0000664 0000000 0000000 00000003765 13500662733 0020466 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = function (t, a, d) {
var x = {}, fn;
fn = function (y, cb) {
setTimeout(function () {
if (cb) {
cb(null, 3);
}
}, 0);
return y;
};
t({}).invoke(fn, x)(function (r) { a(r, x); }).done(d, d);
};
var deferred = require("../../../deferred");
module.exports = function () {
return {
"Function": function (a, d) {
var x = {}, z = {};
z.foo = function (y, cb) {
var self = this;
setTimeout(function () {
if (cb) {
cb(null, self, y);
}
d();
}, 0);
return 3;
};
deferred(z).invoke("foo", x)(function (r) { a(r, 3); }).done();
},
"Method": function (a, d) {
var x = {}, fn, z = {};
fn = function (y, cb) {
var self = this;
setTimeout(function () {
if (cb) {
cb(null, self, y);
}
d();
}, 0);
return 3;
};
deferred(z).invoke(fn, x)(function (r) { a(r, 3); }).done();
},
"Fail": function (a) {
var e = new Error("Error");
deferred(e).invoke("bla")(a.never, function (r) { a(r, e); }).done();
},
"Null input": function (a) {
deferred(null)
.invoke("test")(a.never, function (e) { a.ok(e instanceof TypeError); })
.done();
},
"No Function": function (a) {
deferred({})
.invoke("test")(a.never, function (e) { a.ok(e instanceof TypeError); })
.done();
},
"Promise arguments": function (a) {
var y = {}
, z = {}
, x = {
foo: function (w, u) {
a(this, x, "Context");
a.deep([w, u], [y, z], "Arguments");
return "foo";
}
};
deferred(x)
.invoke("foo", deferred(y), z)(function (r) { a(r, "foo", "Result"); }, a.never)
.done();
},
"Erroneous": function (a) {
var x, fn;
x = new Error("Test");
fn = function () { return x; };
deferred({}).invoke(fn)(a.never, function (e) { a(e, x); }).done();
},
"Function crash": function (a) {
var x = new Error("Test"), fn;
fn = function () { throw x; };
deferred({}).invoke(fn)(a.never, function (e) { a(e, x); }).done();
}
};
};
deferred-0.7.11/test/ext/promise/map.js 0000664 0000000 0000000 00000000413 13500662733 0017733 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t, a, d) {
deferred([deferred(1), deferred(2), 3])
.map(function (res) { return deferred(res * res); })(function (r) {
a.deep(r, [1, 4, 9]);
}, a.never)
.done(d, d);
};
deferred-0.7.11/test/ext/promise/reduce.js 0000664 0000000 0000000 00000000430 13500662733 0020424 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t, a, d) {
deferred([deferred(2), deferred(3), 4])
.reduce(function (arg1, arg2) { return deferred(arg1 * arg2); }, deferred(1))(function (r) {
a(r, 24);
}, a.never)
.done(d, d);
};
deferred-0.7.11/test/ext/promise/some.js 0000664 0000000 0000000 00000000447 13500662733 0020130 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = function (t, a, d) {
var count = 0;
deferred([deferred(1), deferred(2), 3])
.some(function (res) {
++count;
return res > 1;
})(function (r) {
a(r, true);
a(count, 2, "Count");
})
.done(d, d);
};
deferred-0.7.11/test/ext/promise/spread.js 0000664 0000000 0000000 00000001323 13500662733 0020435 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../../deferred");
module.exports = {
Deferred: function (a) {
var defer = deferred(), w = {}, x = {}, y = {}, z = [x, y, w], invoked = false;
defer
.resolve(z)
.spread(function (m, n, o) {
invoked = true;
a(m, x, "#1");
a(n, y, "#2");
a(o, w, "#3");
})
.done();
a(invoked, true, "Resolve in current tick");
},
Promise: function (a, d) {
var w = {}, x = {}, y = {}, z = [x, y, w];
deferred(z)
.spread(function (m, n, o) {
a(m, x, "#1");
a(n, y, "#2");
a(o, w, "#3");
})
.done(d, d);
},
Error: function (a, d) {
var e = new Error("E!");
deferred(e).spread(a.never, function (err) { a(err, e); }).done(d, d);
}
};
deferred-0.7.11/test/ext/promise/timeout.js 0000664 0000000 0000000 00000000733 13500662733 0020651 0 ustar 00root root 0000000 0000000 "use strict";
var Deferred = require("../../../deferred");
module.exports = function (t, a, d) {
var x = {}, deferred = new Deferred(), promise = deferred.promise.timeout(10);
deferred.resolve(x);
setTimeout(function () {
a(promise.value, x);
deferred = new Deferred();
promise = deferred.promise.timeout(10);
setTimeout(function () {
deferred.resolve();
a(promise.failed, true);
a(promise.value.code, "DEFERRED_TIMEOUT");
d();
}, 20);
}, 20);
};
deferred-0.7.11/test/index.js 0000664 0000000 0000000 00000006235 13500662733 0016017 0 ustar 00root root 0000000 0000000 "use strict";
var isFunction = require("es5-ext/function/is-function")
, convert = require("es5-ext/string/#/hyphen-to-camel")
, path = require("path")
, readdir = require("fs").readdir
, indexTest = require("tad/lib/utils/index-test");
var dir = path.dirname(__dirname);
module.exports = {
"": indexTest(
indexTest.readDir(dir)(function (o) {
delete o.assimilate;
delete o.benchmark;
delete o.deferred;
delete o.examples;
delete o.ext;
delete o.promise;
delete o.profiler;
return o;
}),
[
"Deferred", "callAsync", "delay", "extend", "gate", "profile", "profileEnd",
"promisify", "promisifySync", "reject", "resolve", "every", "find", "map", "reduce",
"some", "timeout"
]
),
"isPromise": function (t, a) {
a(t.isPromise(t(null)), true);
a(t.isPromise({}), false);
},
"InvokeAsync": function (t, a, d) {
var x = {};
t.invokeAsync({}, function (cb) {
setTimeout(function () { cb(null, x); }, 0);
return {};
})(function (r) { a(r, x); }).done(d, d);
},
"CallAsync": function (t, a, d) {
var x = {};
t.callAsync(function (cb) {
setTimeout(function () { cb(null, x); }, 0);
return {};
})(function (r) { a(r, x); }).done(d, d);
},
"Delay": function (t, a, d) {
var x = {};
t.delay(function (r) { return r; }, 5)(x)(function (r) { a(r, x); }).done(d, d);
},
"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).done(function () { a(ready, true); });
dy.resolve({});
ready = true;
dx.resolve({});
ready = false;
},
"Profile": function (t, a) {
a(typeof t.profile, "function", "Profile");
a(typeof t.profileEnd, "function", "ProfileEnd");
},
"Promisify": function (t, a, d) {
var x = {};
t.promisify(function (cb) {
setTimeout(function () { cb(null, x); }, 0);
return {};
})()(function (r) { a(r, x); }).done(d, d);
},
"PromisifySync": function (t, a, d) {
t.promisifySync(function () {})()(function (r) { a(r, undefined); }).done(d, d);
},
"Map": function (t, a, d) {
t.map([t(1), t(2), 3], function (res) { return t(res * res); })(function (r) {
a.deep(r, [1, 4, 9]);
}, a.never).done(d, d);
},
"Reduce": function (t, a, d) {
t.reduce([t(1), t(2), 3], function (arg1, arg2) { return t(arg1 * arg2); }, 1)(function (
r
) { a(r, 6); }, a.never).done(d, d);
},
"Some": function (t, a, d) {
var count = 0;
t.some([t(1), t(2), 3], function (res, index) {
++count;
return index;
})(function (r) {
a(r, true);
a(count, 2, "Count");
}, a.never).done(d, d);
},
"Deferred function is main object": function (t, a) {
var d = t();
d.resolve({});
a.ok(isFunction(d.resolve) && isFunction(d.promise.then));
},
"Ports are loaded": function (t, a, d) {
var p = t().resolve();
readdir(dir + "/ext/promise", function (err, files) {
if (err) {
d(err);
return;
}
files
.map(function (file) {
if (file.slice(-3) === ".js" && file[0] !== "_") {
return convert.call(file.slice(0, -3));
}
return null;
})
.filter(Boolean)
.forEach(function (file) { a(isFunction(p[file]), true, file); });
d();
});
}
};
deferred-0.7.11/test/invoke-async.js 0000664 0000000 0000000 00000003326 13500662733 0017314 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../deferred");
module.exports = function (t) {
var u = {}, x = {}, y = {}, z = {};
return {
"Promise arguments": function (a, d) {
t(
u,
function (arg1, arg2, callback) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
},
x,
deferred(y)
)(function (result) { a(result, z); }, a.never).done(d, d);
},
"Normal arguments": function (a, d) {
t(
u,
function (arg1, arg2, callback) {
a(this, u, "Context");
a.deep([arg1, arg2], [x, undefined], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
},
x,
undefined
)(function (result) { a(result, z); }, a.never).done(d, d);
},
"Successful": function (a, d) {
var x = {}, y = {}, z = {};
t(
{},
function (arg1, arg2, callback) {
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, z); }, 0);
},
x,
y
)(function (result) { a(result, z, "Result"); }, a.never).done(d, d);
},
"Successful: Many args": function (a, d) {
var x = {}, y = {}, z = {};
t(
{},
function (arg1, arg2, callback) {
a.deep([arg1, arg2], [x, y], "Arguments");
setTimeout(function () { callback(null, x, y, z); }, 0);
},
x,
y
)(function (result) { a.deep(result, [x, y, z], "Result"); }, a.never).done(d, d);
},
"Erroneous": function (a, d) {
var x = new Error("Test");
t({}, function (callback) {
setTimeout(function () { callback(x); }, 0);
})(a.never, function (e) { a(e, x); }).done(d, d);
},
"Function crash": function (a) {
a.throws(t.bind({}, function () { throw x; }));
}
};
};
deferred-0.7.11/test/is-promise.js 0000664 0000000 0000000 00000000327 13500662733 0016773 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../deferred");
module.exports = function (t, a) {
a(t(deferred().resolve()), true, "Deferred promise is promise");
a(t(deferred({})), true, "Object promise is promise");
};
deferred-0.7.11/test/lib/ 0000775 0000000 0000000 00000000000 13500662733 0015112 5 ustar 00root root 0000000 0000000 deferred-0.7.11/test/lib/some-every.js 0000664 0000000 0000000 00000003471 13500662733 0017550 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../../deferred")
, isPromise = require("../../is-promise");
module.exports = function (t, a) {
var x = {}, y, z = 0, w;
t = t(true);
a(t.call([]).valueOf(), false, "Empty, no cb");
a(t.call([], function () { return true; }).valueOf(), false, "Empty, cb");
a(t.call([{}]).valueOf(), true, "One, truthy, no cb");
a(t.call([0]).valueOf(), false, "One, falsy, no cb");
a(t.call([0, {}]).valueOf(), true, "Two, falsy & truthy, no cb");
a(t.call([0, false]).valueOf(), false, "Two, falsy & falsy, no cb");
a(
t
.call(
(y = [false]),
function (a1, a2, a3) {
++z;
a(a1, false, "Argument");
a(a2, 0, "Index");
a(a3, y, "List");
a(this, x, "Context");
return true;
},
x
)
.valueOf(),
true,
"One, falsy, cb truthy"
);
a(z, 1, "Callback called");
a(t.call([1], function () { return false; }).valueOf(), false, "One, truthy, cb falsy");
a(
t
.call([1, 0], function (x) {
++z;
return !x;
})
.valueOf(),
true,
"Two, cb, Second truthy"
);
a(z, 3, "Callback called twice");
y = deferred();
w = t.call([y.promise, 3, 4]);
a(isPromise(w.valueOf()), true, "In order");
y.resolve(0);
a(w.valueOf(), true, "In order, resolved");
y = deferred();
z = [];
w = t.call([y.promise, 3, 4], function (val) {
z.push(val);
return Boolean(val);
});
a(isPromise(w.valueOf()), true, "In order, cb");
y.resolve(0);
a(w.valueOf(), true, "In order, cb, resolved");
a.deep(z, [0, 3], "In order, cb, called");
y = deferred();
z = [];
w = t.call([0, 3, 4], function (val) {
z.push(val);
return y.promise;
});
a(isPromise(w.valueOf()), true, "Promise cb");
a.deep(z, [0], "Promise cb, processed one");
y.resolve(3);
a(w.valueOf(), true, "Promise cb, resolved");
a.deep(z, [0], "Promise cb, processed, resolved");
};
deferred-0.7.11/test/monitor.js 0000664 0000000 0000000 00000000714 13500662733 0016373 0 ustar 00root root 0000000 0000000 "use strict";
var isValue = require("es5-ext/object/is-value")
, deferred = require("../deferred");
module.exports = function (t, a, d) {
var invoked, df, cachet, cachec;
cachet = t.timeout;
cachec = t.callback;
t(100, function (stack) {
a.ok(stack instanceof Error);
invoked = true;
});
df = deferred();
setTimeout(function () {
a(invoked, true, "Invoked");
t(isValue(cachet) ? cachet : false, cachec);
df.resolve();
d();
}, 150);
};
deferred-0.7.11/test/profiler.js 0000664 0000000 0000000 00000001016 13500662733 0016522 0 ustar 00root root 0000000 0000000 "use strict";
var keys = Object.keys
, deferred = require("../deferred");
module.exports = function (t, a) {
var d1, d2, data;
deferred(1);
t.profile();
deferred(2);
deferred({});
deferred("raz");
d1 = deferred();
d2 = deferred();
d1.resolve(1);
d2.resolve(1);
data = t.profileEnd();
a(data.resolved.count, 3, "Resolved Count");
a(data.unresolved.count, 2, "Unresolved Count");
a(keys(data.resolved.stats).length, 1, "Resolved Stats");
a(keys(data.unresolved.stats).length, 1, "Unresolved Stats");
};
deferred-0.7.11/test/valid-promise.js 0000664 0000000 0000000 00000000517 13500662733 0017460 0 ustar 00root root 0000000 0000000 "use strict";
var deferred = require("../deferred");
module.exports = function (t, a) {
var def = deferred();
a(t(def.promise), def.promise, "Unresolved");
def.resolve(true);
a(t(def.promise), def.promise, "Resolved");
a.throws(function () {
t(function () {});
}, "Function");
a.throws(function () { t({}); }, "Object");
};
deferred-0.7.11/valid-promise.js 0000664 0000000 0000000 00000000307 13500662733 0016476 0 ustar 00root root 0000000 0000000 "use strict";
var isPromise = require("./is-promise");
module.exports = function (value) {
if (!isPromise(value)) {
throw new TypeError(value + " is not a promise object");
}
return value;
};