如何等待async函数执行完成并跨JS文件获取其返回值?
解决异步方法返回值等待与跨文件调用问题
原代码存在的核心问题
- 类结构错误:
delay方法嵌套在constructor内部,不符合JS类语法规范 - 递归调用未返回Promise:
this.redacted(config.pid)调用时没有return,导致异步结果无法向上传递 - 直接打印Promise对象:调用
redacted后立即打印,得到的是未完成的Promise而非最终结果 - 语法错误:
console("MONITOR > No Variants Available")应为console.log
修复后的完整代码
// 假设config、url、req(axios或类似请求库)已在外部定义 class Monitor { constructor(){ this.delay = config.delay; this.err = false; this.oos = false; this.proxy = config.proxy; // 假设config包含代理配置 } // 移到类顶层的延迟方法 delay(time) { return new Promise(resolve => setTimeout(resolve, time)); } async redacted(pid) { if (this.err) { await this.delay(this.delay); } console.log("MONITOR > Getting Item Attrs"); const options = { method: 'get', url: `${url}${pid}.json`, headers: { accept: '*/*', 'accept-encoding': 'gzip, deflate, br', }, proxy: this.proxy }; try { const res = await req(options); const variants = res.data.skus; const inStockAttrs = []; for (const [key, value] of Object.entries(variants)) { if (value.inStock) inStockAttrs.push(key); } if (inStockAttrs.length >= 1) { console.log("MONITOR > Sourced Item"); return inStockAttrs; } else { console.log("MONITOR > No Variants Available"); this.oos = true; // 递归调用必须return,保证Promise链传递 return this.redacted(config.pid); } } catch (err) { if (err?.response?.status === 403) { console.error("MONITOR > Proxy Block @ GET PRODUCT"); this.err = true; return this.redacted(config.pid); } // 处理其他未知错误,避免静默失败 console.error("MONITOR > Request failed:", err); throw err; } } } // 正确等待异步结果的调用方式 (async () => { const monitor = new Monitor(); try { const stockAttrs = await monitor.redacted(config.pid); console.log("最终获取到的库存属性:", stockAttrs); // 此处可将stockAttrs存储到变量或数据库中 } catch (err) { console.error("获取库存属性失败:", err); } })();
关键修复说明
- 规范类结构:将
delay方法移到类顶层,符合JS类的定义规则 - 用await简化异步逻辑:替代嵌套的
then链,提升代码可读性 - 递归调用必须return:确保递归产生的Promise结果能传递到上层调用者,外部才能拿到最终返回值
- 自执行async函数包裹调用:
await只能在async函数内使用,通过自执行async函数实现等待异步方法完成 - 完善错误处理:捕获并抛出未知错误,避免Promise静默失败
跨文件调用方法
假设Monitor类定义在monitor.js中,其他文件调用步骤如下:
1. 导出Monitor类(monitor.js末尾添加)
// CommonJS规范 module.exports = Monitor; // 或ES模块规范 export default Monitor;
2. 在其他文件中导入并使用
// CommonJS方式 const Monitor = require('./monitor.js'); const config = require('./config.js'); // ES模块方式 // import Monitor from './monitor.js'; // import config from './config.js'; async function fetchStock() { const monitor = new Monitor(); try { // 等待异步方法完成,存储返回值 const stockData = await monitor.redacted(config.pid); console.log("跨文件获取的库存数据:", stockData); return stockData; } catch (err) { console.error("跨文件调用失败:", err); return []; } } // 执行调用 fetchStock();
内容的提问来源于stack exchange,提问作者Steve Olla
相关产品推荐
相关产品推荐

