for循环里的异步操作
这周遇到的问题也不少,选一个比较有代表性的出来讲一下,需求是这样的,有一个地方需要循环调用接口来获取数据,一开始我就理所当然地用for循环,两三下就写完了,但当我开始测试的时候就发现不太对劲,获取到的数据出现重复,通过查看后端控制台,发现有几次请求的参数竟然是相同的。
这时候我注意到异步操作在for循环里使用或许会导致程序出现错误,百度了一下,确实如我所想:单线程的js在操作时,对于这种异步操作,会先进行一次“保存”,即把异步操作放到堆栈中,等所有的同步任务执行完成之后才会执行。说白了就是,for大哥并不会停下来等异步兄弟做完他的事情再进行下个循环,这就导致for大哥都跑完循环了,异步兄弟才来找他要值,结果就是拿到了循环结束后的值…
那怎样解决这个问题呢?1、使用递归,将递归的下级入口放在异步操作里,这样子异步操作完才会进入下一层递归。2、使用async、await,在异步操作前加一个await,这就很好理解了,把异步操作变成同步操作,整个代码的易读性也比使用第一种方式要好很多。
这次我明白了原来js里没有真正的异步,因为JavaScript的一大特点就是单线程,而这个线程中拥有唯一的一个事件循环。所谓的异步是借助函数调用栈来完成的,让我不得不感叹一句,数据结构永远滴神!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 被咬了一口の包子°!
评论