That's a general question about using setImmediate (or another similar solutions) for API purpose. I'm writing a node.js library which performs negotiation with a server behind the scene. A client code of this library seems like that:
var request = myLib
.createRequest()
.setRequestProperty('someProperty', someValue)
.setAnotherRequestProperty('anotherProperty', anotherValue)
.performRequest(function callback() {
var someValue = request.someValue;
var requestResult = request.result;
// Some logic based on requestResult and someValue
});
The problem begins when my library does not need to perform or wait to any negotiation with server, thus may call the callback passed to performRequest
immediately. The internal library code may then seems like:
Request.prototype.performRequest = function performRequest(callback) {
if (this._canPerformImmediately()) {
callback();
return this;
}
this._performServerRequest().then(callback);
return this;
};
What happens then is that request is still undefined (as the call to the callback is done before the external statement contains the request assignment is finished).
I wonder what is the correct way to define the API in such cases. I see some possibilities:
- Define that the callback may be called synchronously (as described above), and thus the client code may not use the
request
variable as in the above client code example. However I've seen some code that seems as above, so I guess this is not the solution. Define that the callback may be called synchronously, and that the request is also passed to the callback so the client code may be (Notice the use of
request_
instead ofrequest
):.performRequest(function callback(request_) { var someValue = request_.someValue; var someResult = request_.result; // Some logic based on requestResult and someValue }
(EDIT: The request may be also passed as
this
argument).But again, as I've seen some code that seems as the first example, I guess this is also not the solution.
Guarantee that the callback is called ASYNCHRONOUSLY. Then we can use setImmediate functions. The internal implementation then will look like (Notice the
setImmediate
call):Request.prototype.performRequest = function performRequest(callback) { if (this._canPerformImmediately()) { setImmediate(callback); return this; } this._performServerRequest().then(callback); return this; };
Any other suggestions?
It seems that the setImmediate alternative is the most attractive, but I failed to find discussion about using it for API consideration only. I've seen discussions about performance such as here and here, but no API considerations.
So my question is: What is the correct way to implement such library?