What if something is a callback/async function AND a Promise
See original GitHub issueWorking with request-promise ;
e.g.
var rp = require('request-promise');
var Brakes = require('brakes');
var options = {
uri: 'http://some-json-api.com/',
json: true
};
var brake = new Brakes(request, { timeOut: 1000 });
return brake.exec(options)
.then( response => {
return processResponse(response);
})
.catch(e => {
return processError(e.statusCode);
});
request-promise
wraps the normal request
object, which is a function that has a callback
parameter, and makes it return a promise. Wrapping it causes the behaviour to change because Circuit prefers async callback functions ; instead of the usual behaviour with these options which is for response
to be an object representing the processed JSON response, and for errors to end up in .catch, all responses including errors end up in the .then()
block because Circuit uses the default promise
callback style instead of request-promise
’s Promise wrapping.
Not sure the best way to resolve this but maybe an option to force the Promise treatment instead of using the callback style? Not a big thing to write code to work around this (and ditch request-promise
in the process, since we’re not using it’s features).
Issue Analytics
- State:
- Created 7 years ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
Hey @awilkins, I have used
request-promise
in some projects, and I have generally found that it is best to directly use or wraprequest
. Here is an example of how I wrap it in a promise for use inbrakes
.Hey @sveisvei,
Thanks for the feedback, but there is a problem with both of your examples and the suggestion to check if the passed function is a promise instead of doing the check to see if it is a callback. In your examples you use
Promise.resolve()
which returns a pre-resolved promise. However, the concept of brakes requires you to pass in a function reference that returns a promise (i.e.(opts) => Promise.resolve()
). This is a subtle but important distinction. The first argument has to be a function reference because you may pass in different options to each request, and you will want a new execution on each call instead of referencing the same resolved promise. Moreover, with the lack of return typing in javascript, it is near impossible to do static analysis to determine if a function returns a promise.These are all valid promise functions in js:
You can’t realistically determine if a function returns a promise until after you have executed it, whereas with callback functions you can perform analysis on the function signature. If the analysis of the function signature is inadequate, that is something we can and should improve, but I don’t see how we can replace it with promise detection.
However, after looking at your examples, I think there is an improvement that could be made. Instead of relying solely on the callback detection in
hasCallback
we can add an option that forces brakes to treat the first argument as a callback-function.That would look something like:
In that example, if the
isFunction
flag is set to true, it forces brakes to treat the first argument as a callback instead of a promise.Likewise we could add:
I would be excited and eager to approve a contribution that makes that change 👍
-Alex Wolden