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

React Native Swift原生模块异步调用Promise返回报错解决方案咨询

问题解决建议

核心问题原因

React Native 的 Promise 回调(resolve/reject)必须在主线程执行,RN 桥接操作是绑定主线程的。你在 DispatchQueue.global 这个后台队列里直接调用 resolve,违反了这个规则,所以会触发报错。

解决方法

方法1:切换回主线程调用resolve

在后台任务完成后,通过 DispatchQueue.main.async 切回主线程再执行 resolve,修改后的代码如下:

@objc(voiceRecognizing:withRejecter:)
func voiceRecognizing(resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
    DispatchQueue.global(qos: .userInitiated).async {
        let result = self.recognizeFromMic()
        let resultsDict = [
            "result" : result
        ];
        // 切换到主线程执行resolve
        DispatchQueue.main.async {
            resolve([resultsDict])
        }
    }
}

方法2:完善错误处理(推荐)

如果你的 recognizeFromMic 可能抛出错误,需要在后台线程捕获异常,同样切回主线程调用 reject,避免遗漏错误场景:

@objc(voiceRecognizing:withRejecter:)
func voiceRecognizing(resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
    DispatchQueue.global(qos: .userInitiated).async {
        do {
            // 假设recognizeFromMic会抛出错误,用try捕获
            let result = try self.recognizeFromMic()
            let resultsDict = ["result" : result]
            DispatchQueue.main.async {
                resolve([resultsDict])
            }
        } catch let error as NSError {
            DispatchQueue.main.async {
                reject("VOICE_RECOGNIZE_ERROR", error.localizedDescription, error)
            }
        }
    }
}

额外注意:异步方法的正确调用姿势

如果 recognizeFromMic 本身是带 completion 回调的异步方法(比如基于系统语音识别 API 的实现),不需要额外套全局队列,直接在它的 completion 里切主线程即可:

// 假设你的异步语音识别方法是这种形式
func recognizeFromMic(completion: @escaping (String?, Error?) -> Void) {
    // 内部异步执行语音识别逻辑
}

// 对应RN模块方法的实现
@objc(voiceRecognizing:withRejecter:)
func voiceRecognizing(resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
    self.recognizeFromMic { result, error in
        DispatchQueue.main.async {
            if let error = error {
                reject("VOICE_RECOGNIZE_ERROR", error.localizedDescription, error as NSError)
            } else if let result = result {
                resolve(["result": result])
            } else {
                reject("EMPTY_RESULT", "未获取到识别结果", nil)
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:00:49