javascript - Cordova重复执行异步方法,会覆盖前一个回调函数?

 手机用户2502861905 发布于 2022-11-13 00:41

今天遇到个很奇怪的问题,做一个Hybrid App,用的是Cordova,测试机是ipad,本人负责H5部分(因为不会Object-C orz),所以也看不到原生部分的代码。
问题出现在我重复调用一个原生的异步方法,下面直接贴图↓

下面是重复调用的测试代码

结果打印出来的是这样滴↓
"
进来了
出去了
进来了
出去了
第二次成功
"
???我当时就懵逼了,第一次回调哪去了???

1 个回答
  • 你为什么要连续调用2次?
    Cordova.exec方法执行后,你就等着回调函数的执行,整个过程是异步的~~
    异步函数的回调执行要在当前代码块执行完毕后才有可能被执行~~
    连续调用2次,后一次的回调函数会覆盖前一次的
    看了下exec函数调用逻辑,js会保证每次callback不同,即使同样的方法参数调用:)
    而本地java代码调用后回把callbackId传回给JS
    JS根据callback再调用相应回调函数

    可能是第1次调用本地java代码时候执行出错或超时等原因,而没有返回JS中调用回调函数。而第2次调用时java代码执行成功了,JS回调就被执行....
    具体原因要去看插件执行时是否有错误

    cordova.js代码片段

    ...
    callbackFromNative: function(callbackId, isSuccess, status, args, keepCallback) {
            try {
                var callback = cordova.callbacks[callbackId];
                if (callback) {
                    if (isSuccess && status == cordova.callbackStatus.OK) {
                        callback.success && callback.success.apply(null, args);
                    } else if (!isSuccess) {
                        callback.fail && callback.fail.apply(null, args);
                    }
                    /*
                    else
                        Note, this case is intentionally not caught.
                        this can happen if isSuccess is true, but callbackStatus is NO_RESULT
                        which is used to remove a callback from the list without calling the callbacks
                        typically keepCallback is false in this case
                    */
                    // Clear callback if not expecting any more results
                    if (!keepCallback) {
                        delete cordova.callbacks[callbackId];
                    }
                }
            }
            catch (err) {
                var msg = "Error in " + (isSuccess ? "Success" : "Error") + " callbackId: " + callbackId + " : " + err;
                console && console.log && console.log(msg);
                cordova.fireWindowEvent("cordovacallbackerror", { 'message': msg });
                throw err;
            }
        },
    ...

    exec.js exec代码片段

    ...
    function androidExec(success, fail, service, action,args) {
        if (bridgeSecret < 0) {
            // If we ever catch this firing, we'll need to queue up exec()s
            // and fire them once we get a secret. For now, I don't think
            // it's possible for exec() to be called since plugins are parsed but
            // not run until until after onNativeReady.
            throw new Error('exec() called without bridgeSecret');
        }
        // Set default bridge modes if they have not already been set.
        // By default, we use the failsafe, since addJavascriptInterface breaks too often
        if (jsToNativeBridgeMode === undefined) {
            androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
        }
    
        // Process any ArrayBuffers in the args into a string.
        for (var i = 0; i < args.length; i++) {
            if (utils.typeName(args[i]) == 'ArrayBuffer') {
                args[i] = base64.fromArrayBuffer(args[i]);
            }
        }
    
        //
        var callbackId = service + cordova.callbackId++,
            argsJson = JSON.stringify(args);
    
        if (success || fail) {
            cordova.callbacks[callbackId] = {success:success, fail:fail};
        }
    
        var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
        // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
        // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2.  See CB-2666.
        if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && msgs === "@Null arguments.") {
            androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
            androidExec(success, fail, service, action, args);
            androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
        } else if (msgs) {
            messagesFromNative.push(msgs);
            // Always process async to avoid exceptions messing up stack.
            nextTick(processMessages);
        } } 
        ... 
        
    2022-11-13 00:41 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有