简体   繁体   English

了解异步函数中的执行流程

[英]Understanding execution flow in asynchronous functions

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.当我调用包含此代码的 function 时,将返回 promise。

Inside this function when https.request is executed, I am passing in a callback function.在执行https.request时,在这个 function 内部,我传入了一个回调 function。 In side the https.request code, it will callback this function to process certain events.https.request代码中,它将回调此 function 以处理某些事件。 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.如果检测到连接结束,则执行父 promise 并将数据返回给调用应用程序。

However, later in this function, I am looking at the returned req object and detecting an error event to reject the parent promise.但是,稍后在此 function 中,我正在查看返回的req并检测到error事件以拒绝父 promise。 And finally, the end method of https.request is called to close the connection.最后,调用https.requestend方法关闭连接。

My question is this, when does the code after the https.request execute?我的问题是, https.request之后的代码什么时候执行? That is, the req.on('error'...) and the req.end() .也就是说, req.on('error'...)req.end()

My understanding suggests a couple of different things...我的理解暗示了一些不同的事情......

  1. The https.request returns a promise and then the req.on('error'...) and req.end() code is executed. https.request返回一个 promise 然后req.on('error'...)req.end()代码被执行。 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或者

  1. The https.request blocks execution and a promise is returned to the caller. https.request阻止执行,并将 promise 返回给调用者。 The req.on('error'...) and req.end() does not execute until the https.request resolves. req.on('error'...)req.end()https.request解决之前不会执行。 This would be akin to using await on the https.request ?这类似于在https.request上使用await吗? But, if that were the case, when would I write a stream to the req object to upload a file on a POST request?但是,如果是这种情况,我何时将 stream 写入req object 以在 POST 请求上上传文件? I'm assuming right after the req.on('error'...) and before the req.end() ?我假设在req.on('error'...)之后和req.end()之前? However, if I did that, how would I get a response from the server after the stream completes?但是,如果我这样做了,在 stream 完成后,我将如何从服务器获得响应?

Basically, I would like to understand the program execution flow in the code, along with any explanation why based on the async/promise functionality.基本上,我想了解代码中的程序执行流程,以及基于 async/promise 功能的任何解释。 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.我特别不明白 https.request 是否在异步模式下返回 promise 或基于提供回调 function 的事实在等待模式下阻止代码执行。

I am passing in a callback function.我正在传递一个回调 function。 In side the https.request code, it will callback this function to process certain events.https.request代码中,它将回调此 function 以处理某些事件。

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).该响应是 stream ,然后在其上安装dataend事件侦听器(将再次异步调用)。

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 . "文档说“使用单个参数调用callback ,该参数是http.IncomingMessage的实例。 ”或此处可选的回调参数将作为'response'事件的一次性侦听器添加。

(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) (诚然,我需要链接http文档而不是https文档,因为这些仅记录了与 http 的区别,但在其他方面工作相同)

The https.request returns a promise https.request返回 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. " 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.因此,执行立即从https.request()调用返回,无需等待任何内容。 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.在这个请求 object 上,安装了一个error处理程序,然后通过调用.end()完成(并刷新)请求,因为我们不想发送正文。

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.然后new Promise执行器回调结束,新的 promise 返回到某个地方,通常进行调用的代码将await它或调用.then()在 ZB321DE3BDC299EC807E9F795D 上安装履行/拒绝处理程序。

Only after all this happened, at some later point in time, the response or error events will occur.只有在这一切发生之后,在稍后的某个时间点,才会发生responseerror事件。

end doesn't close the connection. end不会关闭连接。 It actually starts sending it.实际上开始发送它。 The delegate passed to the Promise constructor is executed immediately (before the promise is returned to your code).传递给Promise构造函数的委托会立即执行(在 promise 返回到您的代码之前)。

The delegate passed to request is executed when (and if) the response arrives.当(以及如果)响应到达时,传递给request的委托将被执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM