【问题标题】:How could the FLEX ExternalInterface.available check fail but still be unavailable?FLEX ExternalInterface.available 检查怎么会失败但仍然不可用?
【发布时间】:2012-03-23 01:28:44
【问题描述】:

背景:

我们有几个用 FLEX 编写并在单个 HTML 页面中呈现的 Flash 对象。

我们正在使用 javascript 在对象之间进行通信并执行其他与页面相关的操作。


执行流程:

在我们对象的 FLEX 代码的 creationComplete 事件中,我们执行以下(伪)代码:

if (ExternalInterface.available) {
    ExternalInterface.addCallBack("initialize");
    ExternalInterface.callMethod("ready");
} else {
    Alert.show("No External Interface Available!");
}

执行以下 javascript(伪类)代码:

Object.prototype.ready = function(){
    //this is simplified.  More happens but all we care about is the following
    flexObject.initialize();
}

执行以下 flex(伪类)代码:

public function initialize() {
    var asyncObject:Object = remoteService.executeMethod();
    asyncObject.addResponder(function(object:Object){
        if (ExternalInterface.available) {
            ExternalInterface.callMethod("responseMethod");
        } else {
            Alert.show("ExternalInterface dissapeared!?");
        }
    });
}

应该执行以下 javascript(伪类)代码:

Object.prototype.responseMethod = function() {
    alert("responded!");
}

问题:

有时最后列出的 javascript 函数永远不会被调用。当这种情况发生时,error 警告都不会出现,最终代码只是没有执行,但到目前为止的所有内容都已成功执行。

这种情况在 Chrome/Firefox 中发生大约 1/100 次以上 这在 IE8 中发生了大约 1/10 次 这种情况在 IE7 中发生了大约 9/10 次(完全披露 - 我们必须用于测试的唯一机器也慢得多)

由于问题是间歇性的,并且在较慢的浏览器/机器中变得更加明显,我怀疑它与时间有关。

如果我停止发生第一个 flex 'intiailize' 调用,直到我点击 UI 中的一个按钮,而不是自动点击本质上是 'creationComplete' 的按钮,一切总是有效的。

我可以通过在 javascript 中引入“延迟”来解决问题,但我真的不喜欢这样 hack强>.

【问题讨论】:

  • 试着把你的电话放在 try catch 方法中,看看有什么问题
  • 我现在想知道这是否与调用远程方法后添加响应者有关。
  • 这是一个很好的问题,我想很多人都已经思考过了 :) 之后添加响应者似乎很奇怪。但这实际上是正确的:在获得令牌之前,您无法添加响应者,并且您可以通过调用服务来获取令牌。
  • 虽然服务调用是异步的,但是否有可能在服务调用过程中抛出异常,导致响应者从未添加?

标签: javascript flash apache-flex actionscript externalinterface


【解决方案1】:

我认为@wvxvw 的评论是正确的。

在您的 initialize() 方法中,asyncObject 变量很可能正在被垃圾收集(当问题发生时)。因此,您根本看不到任何错误。

在类级别(不在 initialize() 函数内)声明 asyncObject 变量,这可能会解决问题:

var asyncObject:Object;

public function initialize()
{
    asyncObject = remoteService.executeMethod();
    ....
}

您可能还想考虑使用返回 AsyncToken 的 HTTPService(或其他 flex 服务类),如果您的代码同时发出许多请求,则可以更好地处理响应......

【讨论】:

  • 这个解释似乎很有道理,所以我们实现了一个异步对象的集合,当响应返回时它们会自行清理。 (我的描述中的代码过于简化。在任何给定时间可能会有很多出去,所以我需要保留对所有这些的引用)。由于我们的问题是间歇性的,因此很难知道保持对异步对象的引用是否有帮助。我已经对答案投了赞成票,但现在我不能完全“接受”它,因为我无法证明问题在某些方面仍然不存在。
  • 我不确定我们的修复实施是否不太正确,或者这并没有真正解决问题,但问题今天再次浮出水面:(
  • 上面的initialize() 方法中的removeService 变量的类型是什么,它真的只返回一个Object 吗? ... 只是好奇。如果服务调用失败,将故障处理程序添加到您的 asyncObject 可能很有用。
  • 有一个故障处理程序。它来自春天,所以没有铸造它只是一个“对象”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-01
相关资源
最近更新 更多