GWT JavaScript не ловит исключение - PullRequest
0 голосов
/ 19 мая 2018

При преобразовании апплета с платформой GWT я наткнулся на этот фрагмент кода, где автор узнает длину массива imageNames в цикле, пока не возникнет исключение за пределами допустимого.Это работало в Апплете, но не в GWT!После компиляции GWT браузер зацикливается и не показывает реакцию.Замена исключения на JavaScriptException не помогает.

    boolean error=false;
    int n_img = -1;
    String tmp;
    String[] imageNames;
    ...
    while (!error) {
        try {
            tmp = imageNames[(++n_img)];
        } catch (Exception e) {
            error = true;
        }
    }

Есть ли у вас какие-либо идеи о том, как отловить исключение за пределами GWT?

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Итак, спасибо за комментарий и поясняющий ответ.Это поможет мне в дальнейшем развитии.Теперь я изменил неисправный цикл таким образом

   while (!error) {
        try {
            tmp = this.imageNames[(++n_img)];
            error=(n_img==imageNames.length); // correct severe bug
        } catch (Exception e) {

            error = true;
        }
    }
0 голосов
/ 19 мая 2018

Это один из «недостатков» GWT - во имя производительности дополнительная эмуляция не добавляется, чтобы решить проблему, которую следует избегать.Однако это один из самых явных примеров.

Во-первых, вспомните, что JS, к лучшему или худшему, вполне в порядке, когда вы присваиваете значения индексам в Array s, для которых может не хватить места - выможно использовать это для создания разреженного массива, пропуская далеко за конец массива, вы даже можете назначить отрицательные индексы.

Вдобавок к этой функции Array реализован массив Java, и вместо того, чтобы читать выражение array[n] и переписать его, чтобы проверить n по длине перед назначением (требуется еще две проверки для каждогочитай или пиши) оставляет все как есть.

И, так как обычно операции с массивами, подобные этой, находятся в цикле (например, в вашем коде), это изменение сделает каждый шаг цикла более быстрым, поскольку выполнять проверку границ как часть процедуры тривиально.условие цикла.

и , обычно пользователи Java не пишут код массива на регулярной основе, а опираются на ArrayList или тому подобное - что делает эти проверки (хотя они могутбыть отключен или уменьшен для повышения производительности во время выполнения).

Еще одна причина, по которой это не так уж и плохо: иногда вам хочется писать на Java и ожидать (не без оснований), что вы действительно действуете на выходе JS,Это позволяет использовать такие приемы:

array[array.length] = item;

для увеличения массива с каждым элементом.Очевидно, что в JVM произойдет сбой, но это естественный код для записи в JS.

Наконец, если я не очень сильно ошибаюсь, это даже не очень оптимизированный способ написания этого цикла, даже если бросить и поймать это исключение дешевле, чем просто < проверить каждый шаг цикла - мы все еще проверяем, истинно ли !error каждый шаг!Вместо этого просто заставьте цикл работать вечно и фактически выйдите из него, вместо того, чтобы требовать дополнительного логического значения для отслеживания того, что исключение уже отслеживает для вас:

// just like the code in the question, do not do this, 
// this is just an example of how to get "too clever"
try {
  while (true) {
    tmp = imageNames[(++n_img)];
  }
catch (Exception ignore) {
  // do nothing, something "exceptional" but totally expected has occurred 
}
...