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

QT中使用QNetworkReply时异步调用导致数据为空的问题

解决QNetworkReply异步请求导致parse提前执行的问题

问题根源

QNetworkAccessManager的网络请求是异步非阻塞的,调用fetchDataFromAPI()后函数会立即返回,不会等待API请求完成。你在globals文件里调用fetchDataFromAPI()后马上执行parse(),此时finished()槽函数还没触发,nioshWPDataFromAPI自然是空的。

解决方案

方案一:在请求完成后自动调用parse

直接在finished()函数的成功分支里调用parse(),确保数据准备好后再解析:

void NioshFunc::finished(){
    if(reply->error())
    {
        qDebug() << "ERROR!";
        qDebug() << reply->errorString();
        qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
        qDebug() << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
    }else{
        qDebug() << "SUCCESS";
        qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
        qDebug() << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
        nioshWPDataFromAPI = QJsonDocument::fromJson(dataBuffer);
        qDebug() << nioshWPDataFromAPI;
        dataBuffer.clear();
        
        // 数据就绪后立即解析
        bool parseResult = parse();
        qDebug() << "解析结果:" << parseResult;
    }
    reply->deleteLater();
}

之后globals里只需要调用fetchDataFromAPI()即可,不需要手动调用parse()。

方案二:用信号通知外部解析完成

如果需要在globals里处理解析完成后的逻辑,可以给NioshFunc类添加一个自定义信号,在解析完成后发射:

  1. 先在NioshFunc类的头文件里声明信号:
class NioshFunc : public QObject
{
    Q_OBJECT
signals:
    void dataFetchedAndParsed(bool success); // 自定义信号
    // ... 其他成员
};
  1. 修改parse()函数,最后发射信号(同时修正一处笔误):
bool NioshFunc::parse(){
  Globals *g = Globals::getHandle();
  if (nioshWPDataFromAPI.isEmpty() || nioshWPDataFromAPI.isNull()) {
      emit dataFetchedAndParsed(false);
      return false;
  }
    QVariantMap root = nioshWPDataFromAPI.toVariant().toMap();
    if (root.isEmpty()) {
        emit dataFetchedAndParsed(false);
        return false;
    }
    QVariantMap d = root["d"].toMap();
    if (d.isEmpty()) {
        emit dataFetchedAndParsed(false);
        return false;
    }
    QVariantList results = d["results"].toList();
    if (results.isEmpty()) {
        emit dataFetchedAndParsed(false);
        return false;
    }
    foreach (QVariant varResult, results)
    {
        QVariantMap result = varResult.toMap();
        if (result.isEmpty()) {
            emit dataFetchedAndParsed(false);
            return false;
        }
        g->struct_tableColumn.input.duration = result["Duration"].toString();
        g->struct_tableColumn.input.id = result["Id"].toString();
        // 修正笔误:这里的id应该是全局结构体里的变量
        if (g->struct_tableColumn.input.id.isEmpty() || g->struct_tableColumn.input.id.isNull()) {
            emit dataFetchedAndParsed(false);
            return false;
        }
        g->struct_tableColumn.input.load_cumul_Limit = result["LoadCumulLimit"].toString();
        g->struct_tableColumn.input.Notes = result["Notes"].toString();
        qDebug() << g->struct_tableColumn.input.id << g->struct_tableColumn.input.duration << g->struct_tableColumn.input.load_cumul_Limit << g->struct_tableColumn.input.Notes;
    }
    emit dataFetchedAndParsed(true);
    return true;
}
  1. 在globals里连接信号,处理后续逻辑:
// 假设nioshFunc是NioshFunc的实例
connect(nioshFunc, &NioshFunc::dataFetchedAndParsed, this, [=](bool success){
    if(success){
        // 解析成功后的操作
        qDebug() << "数据解析完成,可以进行后续处理";
    }else{
        qDebug() << "数据解析失败";
    }
});
// 只需要触发请求即可
nioshFunc->fetchDataFromAPI();

额外提示

你parse()函数里原本的if (id.isEmpty() || id.isNull())存在未定义变量的问题,已经在方案二中修正为g->struct_tableColumn.input.id,避免编译报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:15:32