Reputation: 41832
In my project, I have a scenario where I have different kind of functions with different arguments. One of those arguments holds the callback function. And also there is a case where the function doesn't have any arguments. As shown below:
abc(string, function, number)
aaa(function, string)
bcd()
xyz(function)
cda(string, number, function, string)
I need to write a function such that irrespective of the irregularity of above functions, the function should return a promise.
Example:
// Assume $q has been injected
var defer = $q.defer();
function returnPromise(functionName, functionArgumentsInArray){
defer.resolve(window[functionName].apply(null, functionArgumentsInArray));
return defer.promise;
}
As you can see, the above function doesn't resolve the callback function but just the function.
Note: The functions will have max of one function argument or none.
I know it can be done individually for each case as follows:
function returnPromise(){
var defer = $q.defer();
abc("hey", function() {
defer.resolve(arguments);
}, 123);
return defer.promise;
}
But I am looking for a common wrapper for all such functions.
Upvotes: 3
Views: 980
Reputation: 664650
I think you are looking for something like
const cbPlaceholder = Symbol("placeholder for node callback");
function wrap(fn) {
return function(...args) {
return $q((resolve, reject) => {
function nodeback(err, result) {
if (err) reject(err);
else resolve(result);
}
for (var i=0; i<args.length; i++)
if (args[i] === cbPlaceholder) {
args[i] = nodeback;
break;
}
const res = fn.apply(this, args);
if (i == args.length) // not found
resolve(res);
});
};
}
You could use it as
const abcPromised = wrap(abc);
abcPromised("hey", cbPlaceholder, 123).then(…)
Also have a look at How do I convert an existing callback API to promises?. In general you should not need that placeholder thing when all promisified functions follow the convention to take the callback as their last parameter.
Upvotes: 3