问题
So I'm trying to upgrade an existing api to support promises, but I want to maintain backwards compatibility. So, let's say this is my api:
module.exports = {
deliverPost: function(callback) {
someAsyncFunction(function(err) {
if (err)
console.log(err);
callback(err);
});
}
}
That's great, I can call it and pass a callback, and everything works.
Now we do the same thing with promises:
var q = require('q');
module.exports = {
deliverPost: function() {
return q.nfcall(someAsyncFunction).catch(function(err) {
console.log(err);
throw err;
});
}
}
Great, now it returns a promise, but my problem is, any old clients of this api expect to be able to pass in a callback!
So what I really need is something like this:
var q = require('q');
module.exports = {
deliverPost: function(callback) {
return q.nfcall(someAsyncFunction).catch(function(err) {
console.log(err);
throw err;
}).attachNodeStyleCallback(callback);
}
}
So new callers can leverage the promise support, but everything still works if you pass in a callback.
This is a pattern used by, e.g. jQuery.ajax
-- how can I do the same with Q.js
?
Here's an implementation of attachNodeStyleCallback
for reference:
q.makePromise.prototype.attachNodeStyleCallback = function(callback) {
if (!callback)
return this;
return this.then(function(result) {
callback(null, result);
return result;
}, function(err) {
callback(err);
throw err;
})
}
回答1:
The answer is to use promise.nodeify
:
var q = require('q');
module.exports = {
deliverPost: function(callback) {
return q.nfcall(someAsyncFunction).catch(function(err) {
console.log(err);
throw err;
}).nodeify(callback);
}
}
回答2:
You could just test for a callback and run the callback code if it is present:
var q = require('q');
module.exports = {
deliverPost: function(callback) {
if(typeof callback === 'function'){
someAsyncFunction(function(err) {
if (err)
console.log(err);
callback(err);
});
}else{
return q.nfcall(someAsyncFunction).catch(function(err) {
console.log(err);
throw err;
});
}
}
来源:https://stackoverflow.com/questions/20132883/create-an-api-which-accepts-a-callback-and-also-returns-a-promise