我有一个express get方法,该方法又向Git Api发出HTTP请求。我正在使用Http模块调用GIT API,并在promisify方法中调用它。我得到适当的输出。但是,当我从两个不同的浏览器选项卡调用API时,却看到请求是同步执行的。我知道http get会进入事件循环队列,但是即使进入入口的控制台也不会被打印。
_expressApp.get(“ / git”,GitHubService.FetchUser)
public static FetchUser(req:Request, resp:Response,Next:NextFunction)
{
console.log("Going to fetch11");
GitHubService.FetchGitData().then((data)=>
{
console.log("data");
resp.send(data);
}).catch((error)=>
{
resp.send(error);
})
.finally(()=>
{
resp.end();
})
}
private static FetchGitData() : any
{
return new Promise((resolve,reject)=>
{
console.log("Going to fetch");
let data ='';
https.get('https://api.github.com/users/ccrkhere',{headers: {'user-agent': 'node.js','Content-Type': 'application/json'}}, (_resp:any) => {
_resp.on("error",(err)=>{
console.log("Data");
reject(err);
})
_resp.on("data",(chunk)=>
{
data = data + chunk;
})
_resp.on("end",()=>
{
sleep(10000);
console.log("Data");
resolve(data);
})
})
});
}
在两个浏览器标签中调用时的实际结果
要获取1 要获取
要获取1 要获取
预期
要获取1 要获取1 去取 要获取
Node js默认具有两个线程池,因此当发出两个请求时,该任务将分配给两个线程池,这两个线程池将并行继续执行任务。在那种情况下,第一个控制台语句就是我的问题吗?
答案 0 :(得分:0)
您的代码在调用https.get()
之前一直是完全同步的,因此这就是您看到此代码的原因:
Going to fetch 1
Going to fetch
从第一个请求开始,然后再看到其他内容。然后,一旦您触发了第一个异步https.get()
并从中返回,那么下一个传入请求就会从事件队列中拉出,它可以开始处理,然后您会得到:
Going to fetch 1
Going to fetch
来自第二个请求。
请记住,承诺只是通知系统。它只是在完成一些实际的异步操作时通知注册的侦听器。它不会神奇地使任何事物异步化。仅仅因为您进入new Promise()
构造函数中,这并不会使任何异步操作。实际上,promise执行器被同步调用。只有当您开始一些实际的异步操作然后再从该操作中返回时,该node.js才能返回到事件循环并从事件队列中获取下一个事件并对其进行处理。
另外,请删除sleep(10000)
,因为该逻辑类型永远不属于用于处理多个请求/用户的node.js服务器。我不为什么要在这里安装它,但是总有一种更好的方法来解决您要解决的任何问题(可能使用setTimeout()
),而不会阻塞整个服务器。
Node js默认具有两个线程池,因此当发出两个请求时,该任务将分配给两个线程池,这两个线程池将并行继续执行任务。在那种情况下,第一个控制台语句就是我的问题吗?
我不知道您从何处获得此概念,但这不是node.js的工作原理。它具有一个用于运行Javascript的线程。它使用线程池执行一些内部异步操作(例如文件I / O),但该线程池未用于运行Javascript。 node.js运行您的Javascript单线程。当您只有一个node.js进程时,没有两个并行运行每个传入请求的Javascript线程。
如果要使用Javascript的多个线程,则必须使用辅助线程,群集或单独的node.js进程以这种方式专门编程。
答案 1 :(得分:0)
是的,在通过许多站点进行博客发布后,我了解到Promises或async / wait会并行处理。我们可以使用async-await函数来尽快完成任务。