consider the following code. It was grabbed from here.
return new Promise((resolve, reject) => {
const req = https.request(URL, options, res => {
let rawData = '';
res.on('data', chunk => {
rawData = chunk;
});
res.on('end', () => {
resolve(rawData);
});
});
req.on('error', err => {
reject(new Error(err));
});
req.end();
});
I think I've got a pretty clear understanding of how this works.
When I call the function that contains this code, a promise will be returned.
Inside this function when https.request
is executed, I am passing in a callback function. In side the https.request
code, it will callback this function to process certain events. In this case, it looks like to receive data, or to catch the end of the connection. If the end of the connection is detected, the parent promise will be fulfilled and the data will be returned to the calling application.
However, later in this function, I am looking at the returned req
object and detecting an error
event to reject the parent promise. And finally, the end
method of https.request
is called to close the connection.
My question is this, when does the code after the https.request
execute? That is, the req.on('error'...)
and the req.end()
.
My understanding suggests a couple of different things...
- The
https.request
returns a promise and then thereq.on('error'...)
andreq.end()
code is executed. But, if that were true, then it appears it would potentially end the request before it had time to complete the request or process any data.
or
- The
https.request
blocks execution and a promise is returned to the caller. Thereq.on('error'...)
andreq.end()
does not execute until thehttps.request
resolves. This would be akin to usingawait
on thehttps.request
? But, if that were the case, when would I write a stream to thereq
object to upload a file on a POST request? I'm assuming right after thereq.on('error'...)
and before thereq.end()
? However, if I did that, how would I get a response from the server after the stream completes?
Basically, I would like to understand the program execution flow in the code, along with any explanation why based on the async/promise functionality. I specifically don't understand if https.request returns a promise in async mode or blocks code execution in await mode based on the fact a callback function was provided.
CodePudding user response:
end
doesn't close the connection. It actually starts sending it. The delegate passed to the Promise
constructor is executed immediately (before the promise is returned to your code).
The delegate passed to request
is executed when (and if) the response arrives.
CodePudding user response:
I am passing in a callback function. In side the
https.request
code, it will callback this function to process certain events.
No. The callback you're passing is called asychronously (not sure if that counts as "within" in your book) when a response is received. That response is a stream on which then the data
and end
event listeners are installed (which again will be invoked asynchronously).
The docs say "The callback
is invoked with a single argument that is an instance of http.IncomingMessage
." or here "The optional callback parameter will be added as a one-time listener for the 'response'
event."
(Admittedly I needed to link the http
docs instead of the https
ones, since those only document the difference from http but work the same otherwise)
The
https.request
returns a promise
No it doesn't. It returns without blocking, no promises involved.
The docs say: "https.request()
returns an instance of the http.ClientRequest
class. The ClientRequest
instance is a writable stream. If one needs to upload a file with a POST request, then write to the ClientRequest
object."
So execution returns immediately from the https.request()
call, without waiting for anything. On this request object, an error
handler is installed, then the request is finished (and flushed) by calling .end()
since we don't want to send a body.
Then the new Promise
executor callback concludes, the new promise is returned somewhere, and usually the code that made the call will await
it or call .then()
to install fulfillment/rejection handlers on the promise.
Only after all this happened, at some later point in time, the response
or error
events will occur.