11.4 线程阻塞问题
11.4.1 问题描述
Firefox、老版 Chrome 浏览器有一个很独特的问题:js 主线程不允许被插件长时间阻塞。var filename=AF.func("OpenExportDialog", "");或者执行硕正报表同样功能的函数:
var filename=AF.func("callfunc", "103 \r\n type=xlsx");这些函数将弹出一个转换输出选项的模式对话框,在几秒钟后,Firefox极有可能出现如下警告界面, 继而卡死、崩溃:
IE浏览器、新版 Chrome (ppapi) 不存在这个问题.
11.4.2 解决方案
为了解决这个问题,硕正插件从1.0.94.0版开始,增加了一个名为 DeclareAsynch 的新函数,采用多线程方式,将打开对话框的过程安置到新的线程中运行,从而绕开的这个问题。AF.func("DeclareAsynch", ""); AF.func("OpenExportDialog", "");
AF.func("DeclareAsynch", ""); AF.func("callfunc", "103 \r\n type=xlsx");紧挨在 DeclareAsynch 下方的插件函数将被安排在新的线程中运行,并且不等对话框关闭,函数将立即返回,不阻塞主线程。
11.4.3 返回值
用此方案,也导致了一个新的问题:如何获取函数的返回值?var filename=AF.func("OpenExportDialog", ""); //返回 filename, 文件名如果先执行 DeclareAsynch,你会发现返回的 filename 永远是空串!
function onMyMenu() { AF.func("DeclareAsynch", "p1=myFunc"); AF.func("callfunc", "103 \r\n type=xlsx"); } //硕正事件入口 function OnEvent(id, Event, p1, p2, p3, p4) { if(Event == "UserEvent" && p1 =="myFunc") { //这就是线程终止时触发的 //p4就是 callfunc 的返回值 alert(p4); } }分析上面的 js 可知,这本质上就是常规的异步解决方案,异步往往是和多线程、消息事件关联的.
11.4.4 补充说明
1.DeclareAsynch 函数本身和 Firefox、Chrome 无关,在其它浏览器下也一样能使用,所以按上述方案处理,也是能兼容其它浏览器的;