MSx*_*MSx 1 javascript nonblocking node.js express async-await
我们都知道 NodeJS 是单线程的,这意味着如果我们的代码中有 async/await 操作,节点将等待它完成后再执行其余代码。因此,如果用户发出异步请求,其他用户也应该等待它完成后再发出请求吗?
这里我创建了一个简单的示例,第一个路由使用异步函数,需要 10 秒才能发送响应,第二个路由立即发送响应。
当我向第一个路由发送请求并在等待响应时,我向第二个路由发送了另一个请求,并且即使第一个路由尚未完成执行代码,我也得到了响应。
为什么这个例子是非阻塞的?
function sleep(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(true)
},10000)
}).then(val=>val)
}
router.get('/route1',async (req,res)=>{
const test = await sleep()
res.send('HELLO WORLD')
})
router.get('/route2',(req,res)=>{
res.send("HELLO WORLD")
})
Run Code Online (Sandbox Code Playgroud)
await仅阻止/暂停当前函数的执行,而不是整个解释器。事实上,当函数命中函数await内部的第一个时,该函数立即返回一个承诺,并且在该函数(或发生的其他事件)可以自由运行之后进行其他处理。
因此,在您的示例中,当它命中 时await sleep(),该函数执行将暂停,直到await解析/拒绝并且包含async函数立即返回未履行的承诺。由于 Express withrouter.get()没有对返回的 Promise 执行任何操作,因此它只是忽略它并将控制权返回给事件循环。一段时间后,您的第二个请求到达服务器,一个事件被放入 Nodejs 事件队列中,并且 Express 被该事件调用,并为您的第二个路由处理程序提供服务。
因此,如果用户发出异步请求,其他用户也应该等待它完成后再发出请求吗?
不会。只有包含该请求处理程序的一个实例await被挂起。解释器中的其他执行和通过事件循环的其他事件处理程序(例如其他传入请求)仍然可能发生,因此仍然可以处理其他请求,即使一个请求处理程序位于await. 这说明了如何await不阻塞或暂停整个解释器,而仅执行一个函数。
当我向第一个路由发送请求并在等待响应时,我向第二个路由发送了另一个请求,并且即使第一个路由尚未完成执行代码,我也得到了响应。为什么在这个例子中它是非阻塞的?
只有第一条路线被暂停await。其他事件和其他传入请求仍然可以很好地处理。
| 归档时间: |
|
| 查看次数: |
1304 次 |
| 最近记录: |