关于nodejs中异步任务的疑问
发布于 8 年前 作者 cheetahhh 5681 次预览 最后一次回复是 8 年前 来自 问答
小弟以前是做Java开发的(web后端),最近跳槽到一家电商网站,用的是 node.js 。最近在看公司的代码,有一点疑问请大家指点: 举个例子,我们有个功能是店铺上新品之后给关注了这个店铺的人发推送,伪代码是这样的:
async function pushFollowers(shop) {
var start = 0
var size = 100
while (true) {
var followers = await getFollowers(shop.id, {start: start, size: size})
if (followers.length == 0) {
break
}
pushUsers(followers, '通知内容')
start += size
}
}
这里边 pushUsers 也是一个异步函数,就是调用我们接入的一个第三方推送给用户发推送。这里我有点疑问,就这样调用异步函数就可以了吗,如果店铺关注者比较多,那不是要产生很大异步任务,nodejs处理的过来吗?这种情况以前在Java里的话我可能会弄个队列来处理,是不是nodejs自己带了异步队列所以不需要了?这样会有什么问题吗
18 回复
这个就类似于问nodejs为何可以处理高并发的问题。
来自酷炫的 CNodeMD
如果你这个代码和在你线上的web应用上,其它代码不要想执行了,异步不是线程兄弟,不能这样玩,while(true)会柱塞主进程。另开一个node或者子进程吧。 而且就算是可以这样,每个用户都搞个死循环,要死哦。还是一个脚本跑所有用户吧。
来自酷炫的 CNodeMD
@zswnew 求教
@zy445566 有 await 的不会吧?
@cheetahhh 你自己写个两个异步,在第一个执行的异步写while(ture),你看看第二个异步会不会执行
来自酷炫的 CNodeMD
@zy445566 你是说这样吗:
@cheetahhh 我说的while(true)是不break的
这种写法有很大问题,主要有以下几个不合理的地方:
一些可能的解决方案:
@nullcc 非常感谢你的回复,分析的很好。
针对
我有点疑问,在每次
await getFollowers等待数据库响应的时候主线程不是可以处理其他请求吗@cheetahhh 这还要看具体的await方法里面的运算量,如果是I/O密集型,可能问题还不大,如果是计算密集型,问题就大了。不过总的来说,处理这类问题还是不要用上述方案,问题规模不大的时候还能扛住,之后肯定扛不住。
@cheetahhh 你说的是正确的,这里用了async/await,使用while(true)并没有什么问题(不考虑代码规范的话),并不存在上面几个人所说的堵塞当前进程的问题
回到你说的问题,有个疑问,如果NodeJS处理不过来,为什么你觉得加个队列就能处理得过来?
@CoderIvan 消息队列的作用是把生产者的请求路由到后面的异步发送服务(消费者),如果后端异步服务开多个node,效率要比上面代码中单个node跑效率高的多。而且后端服务也未必要是node。
@CoderIvan 如果只是纯异步操作,while(true)是没什么问题,我说的是这种处理问题的方法,每个程序员水平不同,很难避免会在异步方法里面加入CPU密集型的操作,因此这种活尽量不要放在web-server层面做。
@nullcc 兄弟,觉不觉得,扯远了
学习了~
@cheetahhh 我理解加await之后。可以理解当前请求执行的代码是交出执行权的,可以理解当前这个请求是暂停的。这个时候node是可以去处理其他请求。那么当await后面的io完成之后,当前请求就有机会在后面得到执行权,继续执行当前代码。
主调度线程是单线程的, 具体操作的处理是可以多线程的