Promise-Maker
A simple, straight-forward approach to converting callback-based async functions into Promise-based equivalents.
Install and use with:
npm install --save promise-maker
Example 1, making a promise-based version of a callback-based method:
var pMaker = var fs = //create promise-based version of desired methodvar pRead = pMaker //how you would use the standard callback versionfs
Example 2, running a callback-based method in Promise-based form on a one-time basis:
var pMaker = var fs = pMakercompletefsreadFile '/path/to/resource.json' 'utf-8'
Example 3, turning embedded callback-based methods into chainable Promises:
var pMaker = var fs = /*Goal: read a file, parse its content,make an update to its content, and savethe updated version to the original filepath*/ //with callbacksfs
resolve()
?
How Will My Promise Know Which Value to Pass to By default, promise-maker follows the Node.js standard callback argument pattern for determining which value a Promise should pass to resolve()
(or reject()
). The Node.js pattern involves an error hook being passed as the first argument to the callback, followed by the target value of interest as the second argument--for example, cb(err, data)
. Any method which follows this standard callback pattern should be fully compatible with promise-maker right away. For async methods that deviate from this Node.js pattern in a substantial manner though, conversion is still possible by overriding the default rules for selecting a value for Promise resolution (see 'Overriding Standard Value Selection for resolve()
below).
The default approach to value selection is as follows:
- If an error hook is traditionally passed to the async method's callback for handling, and an error has occurred, the Promise will
reject()
with the value of the error object that would normally have been passed to the callback. If an error has not occurred, promise-maker will turn its attention to determining if another value should be passed toresolve()
. - If the async callback within the method would usually be passed 1 argument, this will become the
resolve()
value for the Promise (this is still the case, even for async methods that only pass an error hook to the callback; if an error has not occurred, the Promise will simply resolve with thenull
value held in place of the absent error; this in turn will trigger the next.then()
statement following your Promise). - If the async callback within the method is usually passed 2 arguments, the first argument is assumed to be the standard error hook used by the typical Node.js callback pattern, and the second argument will become the
resolve()
value. - If the async callback within the method would usually be passed 3+ arguments, it will be assumed that the callback pattern does not follow the Node.js standard and the arguments that would be passed to the callback will instead all be resolved together as an array, to give the user access to all of the potential values.
resolve()
Overriding Standard Value Selection For If your async method follows a callback argument pattern that conflicts with the default rules outlined above, you can override these rules using a second optional argument with the create()
method, called the resolves
parameter. This parameter cannot be set for the complete()
method, therefore, if you wish to convert a callback-based method to a Promise-based version, and that callback-based method is not compatible with the default resolve()
values indicated above, you must use create()
to produce a new Promise-based method, instead of attempting to use complete()
to run the method as a Promise on a one-time only basis.
When setting the resolves
parameter, the following options are made available:
-
index number: If
resolves
is set to a number, this number will be applied to an array of the potential callback arguments, with the number serving as an index identifier for the value you would like to see passed toresolve()
(i.e. aresolves
value of0
selects the first argument from the argument array to be passed toresolve()
, a value of1
selects the second argument array value, and so on).
Example 1: If your target method would normally pass three values to the callback, but you are only interested in the third value (instead of the default, which wouldresolve()
all three as an array), you could target this value with the following:
pMake.create(lotsOfCallbackVals, 2)
.
Example 2: Say you have an async method that reverses the standard Node.js argument pattern, passing the desired data as the first argument, with an error hook as the second argument (cb(data, err)
, as opposed tocb(err, data)
), you can instruct your Promise to resolve with the first argument (index 0 in the arguments array), instead of the usual second argument (index 1 of the array), by passing0
as theresolves
parameter:
pMake.create(dataComesFirstMethod, 0)
. -
'all': If you want your promise to
resolve()
with all of the arguments that would usually be passed to the callback, regardless of how many argument values there are, this can be accomplished by setting theresolves
parameter to'all'
. This will lead to all potential callback arguments being resolved as a singular array.
Example: If your async method's callback is normally passed two arguments, but you want both of them passed toresolve()
(instead of the default setting, which would only pass the second argument), this can be accomplished with:pMake.create(needBothValsMethod, 'all')
. -
true: In some cases, you will only be interested in knowing when (and if) your method call has successfully completed. In such cases, you can use the boolean value of
true
as yourresolves
parameter. This has the effect of setting your new Promise-based method to passtrue
toresolve()
upon method completion, while still allowing both for error hooks to be screened, as well as for efficient flow control of asynchronous execution.
Example: If you are using a method that only passes an error hook to the usual callback, such as fs.writeFile, but would like the Promise-based version to resolve withtrue
, instead ofnull
, upon successful completion of file writing, this can be accomplished with:
pMake.create(fs.writeFile, true)
.
API
create(func, [resolves])
func
: The callback-based async method you wish to convert to a Promise-based method.resolves
(optional): Target value you would like your Promise to pass toresolve()
(if different from defaultresolve()
target value).
complete(func, ...args)
func
: The callback-based async method you wish to have executed on a one-time basis as a Promise....args
: The arguments you would usually pass to the main async function, represented byfunc
, when calling it.