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

异步fetch函数返回undefined问题:不修改函数内部的解决方法

异步fetch函数返回undefined的处理方案

问题背景

你有一个意图等待2秒后返回对象的异步fetch函数:

async function fetch() {
    var object;
    await setTimeout(() => { object = { name: 'User', data: 'API Data' } }, 2000);
    return object;
}

调用时希望2秒后显示对象,但执行以下代码时,会同时打印DONE!和错误Cannot read properties of undefined (reading 'name'):

fetch().then((val) => {
    console.log("DONE!"); 
    console.log(val.name);
}).catch((err) => {
    console.log("ERROR!");
    console.log(err);
});

尝试用Promise封装调用也未成功:

let promise = new Promise((resolve, reject) => {
    let request = fetch();
    if (request !== undefined)
        resolve(request);
    else
    reject(request);

}).then((val) => {
    console.log(val);
});

需求:不修改fetch函数内部代码(可删除函数内的async和await,但不能添加Promise等内部逻辑),如何正确判断fetch()已返回有效值再进行打印?


核心问题

原fetch函数中的await setTimeout无效,因为setTimeout不返回Promise,await会直接跳过它,导致函数立即返回undefined;2秒后object才会被赋值,但此时函数已经执行完毕返回了。


解决方案

方案1:删除fetch的async/await,外部轮询检查结果

首先修改fetch函数(仅删除async和await):

function fetch() {
    var object;
    setTimeout(() => { object = { name: 'User', data: 'API Data' } }, 2000);
    return object;
}

然后在外部通过Promise封装轮询逻辑,等待fetch()返回有效值:

function waitForValidResult() {
    return new Promise((resolve, reject) => {
        // 超时逻辑,避免无限等待
        const timeoutId = setTimeout(() => {
            reject(new Error("等待结果超时"));
        }, 5000);

        const checkResult = () => {
            const result = fetch();
            if (result !== undefined) {
                clearTimeout(timeoutId);
                resolve(result);
            } else {
                setTimeout(checkResult, 100); // 每100ms检查一次
            }
        };

        checkResult();
    });
}

// 调用示例
waitForValidResult()
    .then((val) => {
        console.log("DONE!");
        console.log(val.name); // 输出:User
    })
    .catch((err) => {
        console.log("ERROR!");
        console.log(err.message);
    });

方案2:将fetch的object改为全局变量,监听全局变量

如果允许修改fetch中object的作用域(改为全局),可以直接监听这个全局变量:

// 修改fetch:删除async/await,将object改为全局变量
let globalObject;
function fetch() {
    setTimeout(() => { globalObject = { name: 'User', data: 'API Data' } }, 2000);
    return globalObject;
}

function waitForGlobalObject() {
    return new Promise((resolve, reject) => {
        const timeoutId = setTimeout(() => {
            reject(new Error("等待结果超时"));
        }, 5000);

        const check = () => {
            if (globalObject !== undefined) {
                clearTimeout(timeoutId);
                resolve(globalObject);
            } else {
                setTimeout(check, 100);
            }
        };

        check();
    });
}

// 调用示例
waitForGlobalObject()
    .then((val) => {
        console.log("DONE!");
        console.log(val.name);
    })
    .catch((err) => {
        console.log("ERROR!");
        console.log(err.message);
    });

内容的提问来源于stack exchange,提问作者Lepy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:15:38