You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何等待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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:40:27