背景
项目中接入三维模型,由于三维模型团队只提供iframe方式接入和postMessage通讯方式和通讯的数据格式。
//api调用的接口//params传递参数{require:{api:Strubg,params:*}}
刚开始的样子
<divclass="model"><iframesrc="xxx"ref="iframe"/></div>
created(){this.initEvent()},methods:{initEvent(){window.addEventListener('message',this.handleReceive,false)this.$once('hook:beforeDestroy',()=>{window.removeEventListener('message',this.handleReceive,false)})},//接收事件handleReceive(e){console.log(e)//e.data就是接收的数据},//发送事件postMessage({api,params}){constmergeParams={require:{api,params}}this.$refs.iframe.contentWindow.postMessage(mergeParams,'*')}}
//使用的时候this.postMessage({api:'setData'})
简单实现一下,但是发现不能直接拿到调用接口的返回值,只能通过handleReceive
接收值,并回调,这样子很麻烦。
promise改造
思路整理
需要跟三维模型团队约定uuid。
//queue.js/***异步队列*@paramtime-超时时间,单位秒*/exportdefaultclassQueuePromise{constructor(time=15){this.queue=newMap()this.time=time}//加入队列push(uuid,resolve,reject){constparams={uuid,resolve,reject}params.timer=setTimeout(()=>{this.put(uuid)reject({code:-1,msg:'超时'})},this.time*1000)this.queue.set(uuid,params)}//执行队列,并出栈perform(uuid,params){constapiQueue=this.put(uuid)//这里执行resolve,并把结果返回回去apiQueue.resolve(params)}//找到并出栈put(uuid){constapiQueue=this.queue.get(uuid)if(!apiQueue)returnthis.queue.delete(uuid)apiQueue.timer&&clearTimeout(apiQueue.timer)returnapiQueue}clear(){this.queue.forEach(e=>{e.timer&&clearTimeout(e.timer)})this.queue=null}}
+importQueuefrom'./queue'created(){this.initEvent()},methods:{initEvent(){+this.queue=newQueue()window.addEventListener('message',this.handleReceive,false)this.$once('hook:beforeDestroy',()=>{window.removeEventListener('message',this.handleReceive,false)+this.queue&&this.queue.clear()})},//接收事件handleReceive(e){console.log(e)//e.data就是接收的数据+const{api,params,uuid}=e.data?.require||{}+if(uuid)returnthis.queue.perform(uuid,params)//如果有uuid,则去执行resolve或者reject//正常处理你的业务},//发送事件postMessage({api,params}){+returnnewPromise((resolve,reject)=>{constmergeParams={require:{api,params}}+this.$refs.iframe.contentWindow.postMessage(mergeParams,'*')+this.queue.push(objRequest.require.uuid,resolve,reject)+})}}
//使用的时候this.postMessage({api:'setData'}).then(e=>{//拿到返回值console.log(e)})//或者constres=awaitthis.postMessage({api:'setData'})
以上就是postMessage
的Promise
化全过程。