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
相关产品推荐
相关产品推荐

