前天写的一个 js function ,用 ExternalInterface 调用执行了 5 秒钟,百思不得其解,因为用 js 调用仅需 1 微秒。后来突然想到 ExternalInterface 的数据处理 js 源码中使用了递归,而我的 function 返回的是 new 的一个我自己写的类。再仔细看他的代码,大汗!居然 typeof 过后就敢递归!!!在我 return null 后再执行,一微秒。我不能理解给全世界 as 程序员用的官方代码为什么都写得这么凑合!!
实际上,我猜测 mm 写这段代码的人有自己的打算,大部分的对象除了数据对象外,都会有异常,他捕获了,这就是为什么大部分情况下不会出行运行很缓慢的原因(凑巧,我的返回值在 IE 里面没有异常,但是 IE 使用了足足 5 秒钟才完成了递归),试一下递归 window,IE 会有 "Object Error", 而 Firefox 会有 "InternalError: too much recursion",然而他们没有考虑到 IE 处理这个异常需要 50 微妙左右,Firefox 处理这个异常需要 150 微妙左右(在我的机器上),试着运行下面的代码:
var time = getTimer(); var s = "function a(){return window;}"; ExternalInterface.call("eval", s); for (var i:Number = 0; i < 20; i++) { ExternalInterface.call("a"); } var txt=_root.createTextField("txt",10,0,0,100,20); txt.text=getTimer() - time; |
|
在 IE 里面是:1090 左右,而 Firefox 更夸张,基本在 5000 微妙左右。也就是说,我们的 js function 只要是返回一个非纯数据对象的,效率都很差,而这种情况出现的是在太多了,因为很多 function 我们都是写了 as 和 js 公用的,返回个 HTMLElement 是常有的事。于是,决定重载 __flash__toXML() 方法,在调用 ExternalInterface 之前在 as 里面插入下面代码:
var fxml="if(!window.__flash__toXML__)" + "{window.__flash__toXML__=__flash__toXML;" + "window.__flash__toXML=function(v){" + "if(typeof(v)==\"object\"&&v.constructor!=Object)" + "{return null;}" + "return __flash__toXML__(v);};}"; ExternalInterface.call("eval",fxml); |
|
好了,在测试一下上面的循环20次的代码,IE:7 Firefox: 3!!
修改:忘了 typeof(Array) == "object"。修改上面的代码为:
var fxml="if(!window.__flash__toXML__)" + "{window.__flash__toXML__=__flash__toXML;" + "window.__flash__toXML=function(v){" + "if(typeof(v) == \"object\"&&v.constructor != Object&&v.constructor != Array)" + "{return null;}" + "return __flash__toXML__(v);};}"; ExternalInterface.call("eval",fxml |
|