Как проверка FLEX ExternalInterface.available могла завершиться ошибкой, но по-прежнему быть недоступной?

Предыстория:

У нас есть несколько flash-объектов, написанных на FLEX и отображаемых на одной странице HTML.

Мы используем javascript для связи между объектами и выполнения других операций, связанных со страницей.


Поток выполнения:

В событии creationComplete кода FLEX наших объектов мы выполняем следующий (псевдоподобный) код:

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 никогда не вызывается. Когда это происходит, ни одно из предупреждений ошибка не появляется, окончательный код просто не выполняется, но все до этого момента выполнялось успешно.

Это происходит примерно 1/100+ раз в Chrome/Firefox Это происходит примерно 1/10 раза в IE8 Это происходит примерно 9/10 раз в IE7 (полное раскрытие - единственная машина, которую мы должны использовать для тестирования, также намного медленнее)

Поскольку проблема носит периодический характер и становится более очевидной в более медленных браузерах/машинах, я подозреваю, что она связана со временем.

Если я остановлю первый вызов flex 'intiailize' до тех пор, пока я не нажму кнопку в пользовательском интерфейсе, а не автоматически на том, что по сути является 'creationComplete', все ВСЕГДА работает.

Возможно, я смогу решить проблему, просто введя "задержку" в javascript, но мне очень-очень не нравится этот хак.


person Randyaa    schedule 23.03.2012    source источник
comment
Попробуйте позвонить в метод try catch и увидите, что что-то идет не так.   -  person Triode    schedule 23.03.2012
comment
Теперь мне интересно, связано ли это с добавлением ответчика после вызова удаленного метода.   -  person Randyaa    schedule 23.04.2012
comment
Это отличный вопрос, я думаю, что многие люди размышляли над ним :) Кажется странным добавлять ответчика после этого. Но на самом деле это правильно: вы не можете добавить респондента, пока у вас нет маркера, и вы получаете маркер, выполнив вызов службы.   -  person Sunil D.    schedule 23.04.2012
comment
Несмотря на то, что вызов службы является асинхронным, существует ли вероятность того, что во время вызова службы может быть создано исключение, и поэтому ответчик никогда не добавлялся?   -  person Randyaa    schedule 23.04.2012


Ответы (1)


Я думаю, что комментарий @wvxvw уместен.

В вашем методе initialize() очень вероятно, что переменная asyncObject получает сборщик мусора (когда возникает проблема). Таким образом, вы не видите ошибок вообще.

Объявите переменную asyncObject на уровне класса (не внутри функции initialize()), и это, вероятно, решит проблему:

var asyncObject:Object;

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

Вы также можете рассмотреть использование HTTPService (или других гибких сервисных классов), который возвращает AsyncToken и дает вам лучшую обработку ответов, если ваш код делает много одновременных запросов....

person Sunil D.    schedule 29.03.2012
comment
Это объяснение кажется логичным, поэтому мы реализовали набор асинхронных объектов, которые самоочищаются, когда возвращается ответ. (код в моем описании чрезмерно упрощен. В любой момент времени может быть много выходов, поэтому мне нужно сохранить ссылку на все из них). Поскольку наши проблемы были прерывистыми, трудно понять, помогло ли сохранение ссылки на асинхронный объект или нет. Я проголосовал за ответ, но пока не могу его «принять», так как не могу доказать, что проблема каким-то образом не существует. - person Randyaa; 05.04.2012
comment
Я не уверен, что наша реализация исправления не совсем правильная или это не решило проблему, но сегодня проблема снова возникла :( - person Randyaa; 07.04.2012
comment
Каков тип переменной removeService в вашем методе initialize() выше, и действительно ли он возвращает только Object? ... просто любопытно. Может быть полезно добавить обработчик ошибок в ваш asyncObject на случай сбоя вызова службы. - person Sunil D.; 07.04.2012
comment
Есть обработчик ошибок. Он исходит от весны, поэтому без кастинга это просто «Объект». - person Randyaa; 23.04.2012