promise.all 里异步比 for of 循环做异步操作时间更快吗?

2019-06-07 00:27:18 +08:00
 liufei123

按理说 promise.all 里异步是并行的 for of 循环做异步操作是串行的 在 promise.all 方法里运行时间应该更短,但是遇到了问题? 为什么在 promise.all()方法中做 mongoDB 的查询操作 要比在 for of 里的做同样的操作时间更久

async function test(){
	  let userItem=await User.find({},{uid:1,_id:0}).limit(10)
	  console.time('程序耗时 1')
	  for(var item of userItem){
	       await User.findOne({
	           uid:item.uid
	       })
	   }
          console.timeEnd('程序耗时 1')
          console.time('程序耗时 2')
	  await Promise.all(userItem.map(async item=>{
		  let user=await User.findOne({
			  uid:item.uid
		  })
		  return user
	  }))
    console.timeEnd('程序耗时 2')
}
程序耗时 1: 32.129ms
程序耗时 2: 3025.852s

感觉 promise.all 方法查询完之后卡了好久才返回结果 猜测是数据库的连接问题吗?? 求大佬解答!

5840 次点击
所在节点    Node.js
14 条回复
geelaw
2019-06-07 02:13:36 +08:00
是“并发”而不是“并行”。

Promise.all 等价于下面这个写法(不考虑异常情况):

var awaitables = [];
for (var item of userItem)
awaitables.push(User.findOne({ uid: item.uid });
for (var awtb of awaitables)
await awtb;

你可以试试这样做的情况。

另外你的计时方法不好,应该掐头(抹去 JIT 编译)并重复。
WittBulter
2019-06-07 02:55:08 +08:00
你的 `for of` 中的 await 会等待上一个执行完才会执行下一个。
Promise.all 并不会保证顺序,也不等待上一个异步任务执行完,但是可以保证在所有异步全部执行完后才结束。
zjsxwc
2019-06-07 07:02:33 +08:00
试试直接返回 promise 呗,

await Promise.all(userItem.map(item=>{return User.findOne({ uid:item.uid }) }))

楼主原先的写法类似于一群已经拉完屎的人挤在厕所等茅坑。
liufei123
2019-06-07 13:25:18 +08:00
@zjsxwc 对我之后就是直接返回的 promise 但是时间感觉也是差不多 promise.all 还是会卡好久
zjsxwc
2019-06-07 14:00:08 +08:00
@liufei123

不负责任猜测,可能是你的 mongodb 服务器性能太差,n 个请求顺序阻塞处理居然比并发同时处理 n 个请求还快,2333333
liufei123
2019-06-07 16:00:46 +08:00
@zjsxwc 我是开的本地的 localhost 的 有什么影响吗 刚学 node 不久。。
SoloCompany
2019-06-07 17:50:36 +08:00
怀疑你用了 babel 或者 nodejs 使用了出乎意料的优化导致
建议你修改一下程序 1,把循环 await 返回值保存到一个数组里面而不是直接丢弃
iugo
2019-06-07 18:32:24 +08:00
不应该是 User.find 比 User.findOne 快的问题吗?

和 Promise 没有关系.
liufei123
2019-06-07 19:14:58 +08:00
@iugo 下面那个 promise all 也是 findOne 啊哈哈
jiejiss
2019-06-07 19:52:52 +08:00
我感觉是你的 Promise.all 用的不对
把 userItem.map(后面的函数的 async 和 await 去掉试试
iugo
2019-06-07 21:12:27 +08:00
@liufei123 是.

但我的意思是批量获取的时候就不要用 findOne 这种.
liufei123
2019-06-07 23:09:13 +08:00
@jiejiss 后面去掉了 其实结果也是差不多的速度没差多少
jiejiss
2019-06-08 12:51:09 +08:00
那只能是你的 mongodb 的问题了
liufei123
2019-06-08 16:45:19 +08:00
@geelaw 试了下你说的 promise.all 的那种写法 确实是快一些

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/571688

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX