JavaScript异步函数问题:_findService无法返回目标数组
解决你的IP查询服务检测函数返回undefined的问题
嘿,刚看了你的代码,问题主要出在Promise的返回逻辑没理清楚,毕竟刚学JS没多久,踩Promise的坑太正常啦😉 我帮你梳理下问题,再给出修改方案:
核心问题分析
你的$._findService函数现在没有返回任何值,所以调用它自然会得到undefined。虽然你在url_check.then()里做了逻辑处理,但那个回调里的return只是在回调函数内部生效,并不会成为$._findService的返回值。另外,循环里用var i也存在变量提升的潜在问题(这次没触发,但还是得改)。
修改后的代码(先解决核心返回问题)
先把最关键的返回逻辑修好,让函数能正确返回可用服务的数组:
const isServiceAvailable = async url_to_check => { console.log(url_to_check); return await subaybay.an._urlExists("http://" + url_to_check); }; const checkServices = async(json_data) => { return await Promise.all(Object.keys(json_data).map(url_to_check => isServiceAvailable(url_to_check))); }; $._findService = function(json_data) { // 重点:返回整个Promise链,这样调用者能拿到结果 return checkServices(json_data).then(function(values) { // 遍历所有服务,找到第一个可用的 for (let i = 0; i < values.length; i++) { // 用let避免闭包问题 if (values[i] === true) { const targetUrl = Object.keys(json_data)[i]; const targetMapping = json_data[targetUrl]; // 直接返回数组,then会自动把它包装成resolved的Promise return [targetUrl, targetMapping]; } } // 如果没有可用服务,返回undefined(也可以改成抛出错误,看你需求) return undefined; }); };
怎么调用这个函数?
现在$._findService会返回一个Promise,你需要用.then()或者await来获取结果:
// 方式1:用.then()链式调用 $._findService($gameSystem._ipLookupJSON).then(function(availableService) { if (availableService) { console.log("找到可用服务:", availableService); // availableService[0]是URL,availableService[1]是对应的IP/Country/City映射 } else { console.log("没有可用的IP查询服务"); } }).catch(function(error) { console.error("检查服务时出错:", error); }); // 方式2:在async函数里用await(更简洁) async function getWorkingService() { try { const availableService = await $._findService($gameSystem._ipLookupJSON); if (availableService) { console.log("找到可用服务:", availableService); } else { console.log("没有可用的IP查询服务"); } } catch (error) { console.error("检查服务时出错:", error); } } getWorkingService();
额外优化:提前终止检查(更高效)
原来的checkServices用Promise.all会同时检查所有服务,然后等全部完成再判断。其实我们只要第一个可用的服务,完全可以找到就停止,节省时间:
// 优化版:找到第一个可用服务就立刻返回,不用等所有检查 const checkFirstAvailableService = async(json_data) => { const urls = Object.keys(json_data); for (const url of urls) { const isAvailable = await isServiceAvailable(url); if (isAvailable) { return [url, json_data[url]]; } } return undefined; }; // 简化_findService $._findService = function(json_data) { return checkFirstAvailableService(json_data); };
这样修改后,只要检测到第一个可用的服务就会立刻返回,不用浪费时间检查剩下的服务,效率更高~
内容的提问来源于stack exchange,提问作者PE B
相关产品推荐
相关产品推荐

