循环使用axios请求参数异常:传入不同参数却返回相同响应
循环中使用Axios发送请求时,所有响应均为最后一组参数的结果
问题描述
我在循环中使用axios发送请求,为每个请求传入不同的参数,但所有返回的响应都是最后一组参数对应的结果。代码如下:
const axios = require('axios'); const _ = require('lodash'); const querystring = require('querystring'); // 请求地址与基础参数 const url = "https://api-wanbaolou.xoyo.com/api/buyer/goods/list"; let param_default = { game: "jx3", "sort[single_count_price]": 1, size: 500, page: 1, }; const server_map = [ {zone_id:'z01',server_id:'gate0115'}, {zone_id:'z01',server_id:'gate0101'}, {zone_id:'z05',server_id:'gate0519'}, {zone_id:'z05',server_id:'gate0514'}, {zone_id:'z05',server_id:'gate0502'}, {zone_id:'z08',server_id:'gate0807'}, {zone_id:'z21',server_id:'gate2106'}, {zone_id:'z24',server_id:'gate2402'}, ] // 循环发送请求 _.each(server_map,function (server,i){ let param = _.merge(param_default,server) axios.get(url,{ params : param, paramsSerializer: function (param) { return querystring.stringify(param) } }).then((res) => { // 所有返回的数据都是最后一组参数的结果 }) })
我原本认为每个请求的param都是不同的,响应应该正确,但实际结果不符合预期,请问这是为什么?该如何解决?
问题根源与解决方案
问题原因
你遇到的核心问题是**_.merge的使用方式导致所有请求共享了同一个参数对象**,再结合axios请求的异步特性,最终所有请求都使用了最后一次循环修改后的参数。
具体来说:
_.merge函数的特性是会修改第一个传入的对象,并返回这个被修改的对象。你写的let param = _.merge(param_default, server),本质是把全局的param_default和当前server合并,修改了param_default本身,然后把这个已修改的param_default赋值给param。- 所有循环中的
param变量其实都是指向同一个param_default对象的引用。由于axios请求是异步的,循环会快速执行完毕,当所有请求真正开始处理参数时,param_default已经被最后一次循环的server数据修改完成,因此所有请求都使用了最后一组参数。
解决方法
解决的关键是每次合并参数时,基于原始的param_default创建全新的独立对象,避免修改原对象。只需调整_.merge的写法:
// 修改合并参数的代码:先传空对象作为基础,再依次合并param_default和当前server let param = _.merge({}, param_default, server);
这样每次循环都会生成一个独立的param对象,彼此之间不会互相覆盖,axios异步请求处理时就能拿到各自对应的参数了。
如果你不需要处理深层嵌套的对象,也可以用Object.assign实现类似效果(浅拷贝):
let param = Object.assign({}, param_default, server);
如果param_default是深层嵌套的结构,_.merge({}, param_default, server)依然是更稳妥的选择,因为它能正确处理深层属性的合并。
修改后,每个请求的参数都是独立的,就能得到对应服务器的正确响应了。
内容的提问来源于stack exchange,提问作者iRuxu
相关产品推荐
相关产品推荐

