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

AsyncWorker.OnOK中调用Promise::Deferred.Resolve()触发崩溃如何解决

问题根因

FileMd5Async函数中声明的Napi::Promise::Deferred deferred是栈上局部变量,函数执行结束返回Promise后,该栈变量会被销毁。HashAsyncWorker类中存储的是deferred的左值引用,OnOK回调触发时访问的是已经被释放的内存地址,直接触发段错误。

修复方案
  1. 将HashAsyncWorker的deferred成员变量从引用类型改为值类型。Napi公开的所有值类型本质都是V8对象的句柄,拷贝操作仅增加句柄引用计数,开销极低,且会保证内部关联的Promise对象不会被提前回收。
  2. 可删除自定义的env成员变量,Napi::AsyncWorker基类已经提供Env()方法可直接获取当前环境对象,避免重复持有引用带来的额外风险。

修改后的代码示例

HashAsyncWorker.h

#pragma once
#include "third_party/node-addon-api/napi.h"

class HashAsyncWorker : public Napi::AsyncWorker {
    public:
        HashAsyncWorker(Napi::Env &env, Napi::Promise::Deferred deferred, std::string filePath);
        ~HashAsyncWorker() override {};

        void Execute() override;
        void OnOK() override;
        void OnError(Napi::Error const &error) override;

    private:
        Napi::Promise::Deferred deferred;
        std::string filePath;
        std::string hashResult;
};

HashAsyncWorker.cc 构造函数

#include "HashAsyncWorker.H"
#include "hash_utils.h"

HashAsyncWorker::HashAsyncWorker(Napi::Env &env, Napi::Promise::Deferred deferred, std::string filePath) 
: Napi::AsyncWorker(env), deferred(std::move(deferred)), filePath(filePath), hashResult("") {

}

// Execute、OnOK、OnError方法无需修改
void HashAsyncWorker::Execute() {
    hashResult = hash_utils::FileMd5(filePath);
}

void HashAsyncWorker::OnOK() {
    deferred.Resolve(Napi::String::New(Env(), hashResult)); 
}

void HashAsyncWorker::OnError(Napi::Error const &error) {
    deferred.Reject(error.Value());
}

原FileMd5Async函数的逻辑无需任何调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:51:03