Ionic JavaScript do-while循环条件导致错误

dxxyhpgq  于 2023-11-15  发布在  Ionic
关注(0)|答案(2)|浏览(138)

我正在运行一个旧版本的Ionic v1,不再支持。似乎我发现了一个任何地方都没有涉及的错误。它的唯一两个提及是1)与collection-repeat有关,我没有在我的应用程序中运行,2)我自己以前的问题(S)关于试图解决错误。
我的生产应用程序报告的错误,在数千个会话中只发生了十几次-但我无法复制它或准确地确定何时/何地/如何触发它。罪魁祸首函数是anchorScroll,我认为在一个模式中使用ng-repeat在160个项目的列表上滚动时被触发。我相信它与此相关的唯一原因是因为唯一的其他时间curElm.attributes在谷歌搜索中提到的是一个离子collection-repeat和,当结合的事实,我曾经在这个ng-repeat最项目是20项,我相信160列表是这里滚动罪魁祸首的一部分.但我不知道肯定.
这来自Ionc v1 ionic.bundle.js,第60723行

self.anchorScroll = function(shouldAnimate) {
    self.resize().then(function() {
      if (!scrollView) {
        return;
      }
      var hash = $location.hash();
      var elm = hash && $document[0].getElementById(hash);
      if (!(hash && elm)) {
        scrollView.scrollTo(0, 0, !!shouldAnimate);
        return;
      }
      var curElm = elm;
      var scrollLeft = 0, scrollTop = 0;
      do {
        if (curElm !== null) scrollLeft += curElm.offsetLeft;
        if (curElm !== null) scrollTop += curElm.offsetTop;
        curElm = curElm.offsetParent;
      } while (curElm.attributes != self.element.attributes && curElm.offsetParent);  // ERROR HERE
      scrollView.scrollTo(scrollLeft, scrollTop, !!shouldAnimate);
    });
  };

字符串
什么是修补上述函数的最佳方法,使其不会触发以下错误?

Exception = null is not an object (evaluating 'curElm.attributes')
Stack = @ionic://attendago/lib/ionic/js/ionic.bundle.js:60723:22
processQueue@ionic://attendago/lib/ionic/js/ionic.bundle.js:29132:30
@ionic://attendago/lib/ionic/js/ionic.bundle.js:29148:39
completeOutstandingRequest@ionic://attendago/lib/ionic/js/ionic.bundle.js:19199:15
@ionic://attendago/lib/ionic/js/ionic.bundle.js:19475:33


是否简单地将while语句重写为如下:

} while (curElm && curElm.attributes != self.element.attributes && curElm.offsetParent);


或者在curElm assignment期间测试null:

if (curElm !== null) curElm = curElm.offsetParent;


......还是别的什么?因为我还没有能够复制的问题,我不能真正测试我自己的补丁,所以我需要特别小心,我自己的补丁不会造成更多的问题。
所有其余的跟踪似乎都与延迟的进程队列有关,如果有帮助,请添加它们:1st@line:19475

self.defer = function(fn, delay) {
    var timeoutId;
    outstandingRequestCount++;
    timeoutId = setTimeout(function() {
      delete pendingDeferIds[timeoutId]; 
      completeOutstandingRequest(fn);   //19475 ***
    }, delay || 0);
    pendingDeferIds[timeoutId] = true;
    return timeoutId;
  };


第二行:19199

function completeOutstandingRequest(fn) {
    try {
      fn.apply(null, sliceArgs(arguments, 1));  //19199 ***
    } finally {
      outstandingRequestCount--;
      if (outstandingRequestCount === 0) {
        while (outstandingRequestCallbacks.length) {
          try {
            outstandingRequestCallbacks.pop()();
          } catch (e) {
            $log.error(e);
          }
        }
      }
    }
  }


第三条@线:29148

function scheduleProcessQueue(state) {
    if (state.processScheduled || !state.pending) return;
    state.processScheduled = true;
    nextTick(function() { processQueue(state); });  //29148 ***
  }


第4位@线:29132

function processQueue(state) {
    var fn, deferred, pending;

    pending = state.pending;
    state.processScheduled = false;
    state.pending = undefined;
    for (var i = 0, ii = pending.length; i < ii; ++i) {
      deferred = pending[i][0];
      fn = pending[i][state.status];
      try {
        if (isFunction(fn)) {
          deferred.resolve(fn(state.value));  //29132 ***
        } else if (state.status === 1) {
          deferred.resolve(state.value);
        } else {
          deferred.reject(state.value);
        }
      } catch (e) {
        deferred.reject(e);
        exceptionHandler(e);
      }
    }
  }

noj0wjuj

noj0wjuj1#

就像你提到的,当你不能复制这个问题时,很坚韧弄清楚。
你的日志/错误状态是curElm为“null”,所以你应该尽量避免使用/ test来处理这种情况。
我认为var curElm = elm;可能是导致这个问题的原因。你可以尝试使用'let'而不是var。我担心的是,由于var声明,另一个函数可能会从另一个代码块重新分配这个变量。
另一个地方是

curElm = curElm.offsetParent;

字符串
我认为修改while条件可能是有益的:

while ( curElm !== null && curElm.attributes != self.element.attributes && curElm.offsetParent);  // ERROR HERE


我希望这对你有帮助:)

dgiusagp

dgiusagp2#

对于任何遇到这个问题的人,这就是我处理它的方式。
在ionic.budle.js中,我将60723行从:

while ( curElm.attributes != self.element.attributes && curElm.offsetParent);

字符串

while ( curElm && curElm.attributes != self.element.attributes && curElm.offsetParent);


注意:我不完全知道这对性能或滚动有什么影响;但至少它不会再产生错误了。

相关问题