以下所有操作都是使用的 mongoose ,另外 schema 和 model 定义这些无关紧要的部分统统省略了,无需深究代码的细节处。
需求
跨表循环遍历查询:从第一个表中查询所有匹配的数据,结果为 doc ,数组形式。从 doc 数组中遍历每一个元素的 phone 属性,去另外一张表中查询 phone 匹配的数据,合并对象,然后返回结果。
过程
第一阶段:天真的想当然
知道点异步流程的同学都明白,最终的result肯定是为空的。
第二阶段:加个计数器吧
加个计数器,然后一直循环判断计数是否完成。OK,又是一个想当然,程序最终会一直在 while 里死循环。
为什么这样不行?我们都知道 node 是基于异步的事件循环机制,但是当我们这里使用 while 循环判断时,这个 while 本质上是一个同步的代码,其是无法与事件循环机制的钩子对接,所以无法跳出这个同步的 while 循环。
第三阶段:算了不绕弯子了。
你肯定想问,上面两个阶段我为什么还在用回掉函数这么老掉渣的写法而不是 promise 呢,因为在 promise 里是不会有类似于 for 、map 这种循环遍历的,涉及到这种操作,应该用 promise.all 方法。( promise 不熟,赶紧去补课吧 )
当然这里也用到了 es6 的对象浅拷贝,不过多论述。
结语
第二阶段的同步阻塞是很容易忽略和想当然的地方,第三阶段当我们要在 promise 中使用类似于 for 、map 这种循环时,其实应用使用的是 promise.all,另外如果你写出了 promise 嵌套 promise 的情况,我觉得你应该重新思考下 promise ,就这样吧,记录一个很小的问题,至于 async/await 暂时还不想写在这里。