如何将while循环放入async函数并await后发送Axios POST请求?
如何让while循环中的异步请求完成后再执行POST请求
我来帮你理清楚问题所在,以及如何正确实现你的需求~
你的核心问题在于:原来的代码里,你创建的Promise并没有等待所有fetch请求完成就结束了(甚至没有调用resolve),所以await vm.fetchDNSData()其实根本没等到所有DNS查询完成,就直接执行了Axios POST,这时候vm.dnsResult里的数据还没收集全。
下面给你两种可行的解决方案,根据你的需求选择:
方案1:并行执行所有请求(推荐,效率更高)
因为你的DNS查询之间没有依赖关系,同时发起所有请求,再等待全部完成是最优的做法:
fetchDNSData: async function () { const vm = this; const randomCallCount = Math.floor(Math.random() * (80 - 50 + 1) + 50); // 用数组存储所有fetch请求的Promise const fetchTasks = []; for (let start = 1; start <= randomCallCount; start++) { const randomChars = [...Array(40)].map(i => (~~(Math.random() * 36)).toString(36)).join(''); // 每个fetch操作返回一个Promise,加入数组 const task = fetch(`https://${randomChars}.ipleak.net/json/?query_type=mydns`) .then(resp => resp.json()) .then(data => { vm.dnsResult.push(data); }); fetchTasks.push(task); } // 等待所有Promise都完成 await Promise.all(fetchTasks); }, showResults: async function () { const vm = this; const apiUrl = '/api/test'; // 等待所有DNS查询完成 await vm.fetchDNSData(); // 现在dnsResult已经收集了所有数据,可以安全发送POST try { const response = await axios.post(apiUrl, { lat: vm.geoLat, lon: vm.geoLon, dns: vm.dnsResult }); // 处理POST成功的逻辑 } catch (error) { // 处理请求失败的逻辑 console.error('POST请求失败:', error); } }
方案2:串行执行请求(逐个等待完成)
如果你的场景需要按顺序执行每个DNS查询(比如前一个请求完成后再发下一个),可以用await在循环内部等待每个fetch完成:
fetchDNSData: async function () { const vm = this; const randomCallCount = Math.floor(Math.random() * (80 - 50 + 1) + 50); for (let start = 1; start <= randomCallCount; start++) { const randomChars = [...Array(40)].map(i => (~~(Math.random() * 36)).toString(36)).join(''); // 等待当前fetch请求完成 const resp = await fetch(`https://${randomChars}.ipleak.net/json/?query_type=mydns`); const data = await resp.json(); vm.dnsResult.push(data); } }, // showResults函数和方案1一样,用await等待fetchDNSData完成 showResults: async function () { const vm = this; const apiUrl = '/api/test'; await vm.fetchDNSData(); try { const response = await axios.post(apiUrl, { lat: vm.geoLat, lon: vm.geoLon, dns: vm.dnsResult }); // 处理成功逻辑 } catch (error) { console.error('POST失败:', error); } }
为什么你原来的写法无效?
- 你创建的Promise内部没有调用
resolve(),所以这个Promise永远不会进入fulfilled状态,await promise会一直等待下去(或者说代码会卡在那里)。 - 即使你加了
resolve(),while循环只是批量发起了fetch请求,但没有等待这些请求完成,resolve()会在循环结束后立即执行,这时候大部分fetch还在后台运行,vm.dnsResult还没收集到数据。
内容的提问来源于stack exchange,提问作者Wathfea
相关产品推荐
相关产品推荐

