使用MUI开发过程中遇到多个页面 子页面调用父页面的方法并且同步或者异步获取数据方式使用Promise形式获取父页面返回的数据方法。
Tip: 引入了 lodash 库
子页面定义方法:
const Invoking = {
task: [],
invoking(method, params) {
let job = {};
job.id = method + new Date().getTime();
job.state = false;
job.result = null;
job.timer = null;
job.task = new Promise((resovle, reject) => {
if (job.state == true) {
reject("Wait..");
return;
}
let target = plus.webview.getWebviewById("main");
if (target == null) {
reject("WebView Null");
return;
}
job.state = true;
target.evalJS(`CallMethods.${method}(${params},'${job.id}')`);
job.timer = setInterval(() => {
if (job.state == false) {
//执行完毕了
clearInterval(job.timer);
//移除操作
_.remove(Invoking.task, function (n) {
return n.id == job.id;
});
resovle(job.result);
}
}, 100);
});
this.task.push(job);
return job.task;
},
callBack(obj, id) {
let task = _.find(this.task, { "id": id });
task.result = obj;
task.state = false;
}
}
父页面定义方法:
/**
* 公共的调用方法
*/
const CallMethods = {
/**
* 获取资源文件
* @param {*} media
*/
getMediaUrl(media, id) {
console.log("调用:", id)
vm.jimClient.getMedia(media).then(url => {
pushInvoking({ code: 200, result: url }, id);;
}).catch(err => {
pushInvoking({ code: 500, result: err }, id)
})
}
}
/**
* 将调用的结果返回到子WebView
* @param {*} obj
*/
function pushInvoking(obj, id) {
plus.webview.getWebviewById("chat").evalJS(`Invoking.callBack(${JSON.stringify(obj)},'${id}')`);
}
子页面使用方法:
//下载图片
Invoking.invoking("getMediaUrl", `'${msg.msgBody.media_id}'`)
.then(url => {
console.log("下载完成Url:===>", url);
}).catch(err => {
console.error("调用错误:", err);
})
这里原理是使用定时器+Flag模式 定时器每隔段时间判断标记位Flag的状态 如何为False 那么就删除掉定时器 从task任务中移除自身对象,并且返回数据。
因为每个任务给了一个编号Id 所以传给父页面需要带着Id过去,父页面回调JS的时候 需要带数据与Id传过来,子页面通过数组搜索找到任务给他赋值结果,设置标记位为完成状态。