JsBridge的异步不执行的处理--promise异步变同步

Hybird App:H5内嵌APP,前端用vue,APP之间的交互处理,适配安卓ios, 为了降低开发成本,减少前端适配工作量,三端统一使用  WebViewJavascriptBridge

在进行后端接口请求的时候统一先把参数返给APP端,APP端进行加密之后,再返回给前端,前端再进行异步请求

由于这里涉及到异步操作,异步请求可能会在和APP交互之前执行,那样就得不到APP返回的加密参数就执行了请求,所以是请求不到结果的,实际是要有先后顺序的,要一步一步的操作,上一步成功之后进行下一步操作,

所以最终利用promise把APP,H5和后端之间的交互进行同步处理,一步一步进行交互操作,最终成功

1. 先写web端的bridge.js

var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
// alert('是否是Android:'+isAndroid);
// alert('是否是iOS:'+isiOS);
function setupWebViewJavascriptBridge(callback) {
  if(isAndroid){
    if (window.WebViewJavascriptBridge) {
    callback(WebViewJavascriptBridge)
    } else {
      document.addEventListener('WebViewJavascriptBridgeReady', function (event) {
          if(window.onWebViewJavascriptBridgeReady) window.onWebViewJavascriptBridgeReady(window.__bridge = WebViewJavascriptBridge);
          callback(WebViewJavascriptBridge)
      }, false)
    }
  }
  
  if(isiOS){
    if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
    if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
  }
  
}

export default {
  callhandler (name, data, callback) {
    setupWebViewJavascriptBridge(function(bridge) {
      bridge.callHandler(name, data, callback)
    })
  },
  registerhandler (name, callback) {
    setupWebViewJavascriptBridge(function (bridge) {
      bridge.registerHandler(name, function (data, responseCallback) {
        callback(data, responseCallback)
      })
    })
  }
}

2. 封装和APP交互的方法 callBridge.js

export default {
    methods:{
        callBridgefn(json){ // 调用app加密方法
            let p = new Promise((resolve, reject)=>{
                this.$bridge.callhandler('encryptParams', JSON.stringify(json),(data) =>{  //encryptParams是APP端规定的方法名
            resolve(data) })
})
return p;
},
    goBack(){ // 调用APP的返回
      
this.$bridge.callhandler('goBack', (data) =>{ // goBack是APP端规定的方法名
    })
  }
}
}

3. 利用promise重写axios异步请求方法 promise.js

import axios from 'axios'

export default{
    methods:{
     sendServer(param) { 
        return new Promise((resolve,reject)=>{            
                axios.post(url ,param).then(res=>{ // url为请求地址
                resolve(res.data)
            }).catch(err=>{
                reject(err)
            })
        })
     },
    }
}
    

4. 页面中请求接口的方法

_sendServer(param){
this.callBridgefn(param).then(data=>{
  this.sendServer(JSON.parse(data))
    .then(res=>{
                // 这里写要对后端返回的数据进行的操作
            })
        })
}

5. 在页面初始化的时候调用

created(){
     this._sendServer(param) //param是要传递给APP进行加密的参数
}

 

posted @ 2018-11-02 18:30  c-137Summer  阅读(1521)  评论(1编辑  收藏  举报