I'm trying to promisify a 3rd party library that doesn't use the callback(err, data)
pattern. Instead they always return callback(data)
and throw
on errors.
Promise.promisifyAll(horse);
var p = Promise.defer();
horse.drinkAsync()
.error(function(data)
{
p.fulfill(data);
})
.catch(function (err)
{
console.error('error occured', err);
});
return p.promise;
What is a nice way to wrap such a behavior with promises and still have it look ok and allow to catch the thrown error? The catch clause doesn't trigger and the application crashes.
To convert a callback into a promise, you need to return a promise. You run the code with the callback inside the promise. const readFilePromise = () => { return new Promise((resolve, reject) => { fs. readFile(filePath, options, (err, data) => { // ... }) }) }
promisify() method basically takes a function as an input that follows the common Node. js callback style, i.e., with a (err, value) and returns a version of the same that returns a promise instead of a callback.
If the callback function returns non-error output, we resolve the Promise with the output. Let's start by converting a callback to a promise for a function that accepts a fixed number of parameters: const fs = require('fs'); const readFile = (fileName, encoding) => { return new Promise((resolve, reject) => { fs.
promisify. Returns a function that will wrap the given nodeFunction . Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function.
From Bluebird 2.1 on, you can now customize promisifyAll
with a custom promisification handler:
function noErrPromisifier(originalMethod){
return function promisified() {
var args = [].slice.call(arguments); // might want to use smarter
var self = this // promisification if performance critical
return new Promise(function(resolve,reject){
args.push(resolve);
originalMethod.apply(self,args); // call with arguments
});
};
}
var horse = Promise.promisifyAll(require("horse"), {
promisifier: noErrPromisifier
});
horse.drinkAsync().then(function(data){
// Can use here, ow promisified normally.
});
If the original method throws asynchronously, there is really no way around wrapping it in a domain, although I've never seen a library that acts that poorly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With