jQuery API调用异常:加密货币信息重复插入同一列问题排查
问题分析与解决方案
嘿,我一眼就看出问题所在啦——这是异步请求的闭包陷阱搞的鬼!
为什么所有数据都跑到crypto-3里?
你的jQuery.get()是异步请求,意味着代码不会等着请求返回再执行下一次循环。当所有请求的回调函数终于触发时,循环里的变量i早已经跑完了整个循环,变成了3(因为你的cryptos数组有3个元素,循环结束后i从0递增到3)。所以所有回调里的$("#crypto-"+i)其实都是$("#crypto-3"),自然所有数据都堆到这个列里了。
两种简单的修复方案
方案1:利用jQuery.each的内置索引
直接用each方法提供的index参数,不用自己维护i变量,每个迭代的索引都是独立的:
function fillGrid() { var cryptos = ["bitcoin","ethereum","ripple"]; jQuery(cryptos).each(function(index, cryptoName){ jQuery.get("https://api.coinmarketcap.com/v1/ticker/"+cryptoName+"/", function(data) { jQuery("#crypto-"+index).append(data[0].name); }); }); };
方案2:用let创建块级作用域变量
如果习惯用for循环的话,把var i改成let i,ES6的let会在每次循环迭代中创建一个新的变量绑定,确保回调里拿到的是当前迭代的i值:
function fillGrid() { var cryptos = ["bitcoin","ethereum","ripple"]; for(let i = 0; i < cryptos.length; i++){ let crypto = cryptos[i]; jQuery.get("https://api.coinmarketcap.com/v1/ticker/"+crypto+"/", function(data) { jQuery("#crypto-"+i).append(data[0].name); }); } };
额外小建议
还可以考虑用Promise.all()来处理多个异步请求,这样能更好地控制请求的完成顺序,不过对于当前需求来说,上面两种方案已经完全够用啦。
内容的提问来源于stack exchange,提问作者Remco Bravenboer
相关产品推荐
相关产品推荐

