不能使用'in'运算符在undefined中搜索'sth'

时间:2016-09-27 01:33:10

标签: javascript jquery ajax

这是我的代码:

.
.
keydown: function(ev) {

    clearTimeout( $(this).data('timer') );
    if ( 'abort' in $(this).data('xhr') ) $(this).data('xhr').abort();       // error here
    var xhr, timer = setTimeout(function() {
        xhr = $.ajax({
            url :  '/files/tags_autocomplete.php',
            dataType : 'JSON',
            success : function (tags) {
            $("ul").html(tags.output);
            }
        });
    }, 500);

    $(this).data({timer : timer, xhr : xhr});
}
.
.

正如我评论的那样,第三行引发了这个错误:

  

未捕获TypeError:无法使用'in'运算符在未定义中搜索'abort'

我该如何解决?

3 个答案:

答案 0 :(得分:2)

更改自:

if ('abort' in $(this).data('xhr') ) $(this).data('xhr').abort(); 

为:

if ($(this).data('xhr') && $(this).data('xhr').abort) {
  $(this).data('xhr').abort(); 
}

问题只是检查对象是否有xhr元素。默认情况下,它不存在,因此它是undefined,并且您要求JS引擎在undefined信息中找到导致错误的元素。

这就是为什么我添加以检查它是否有.data('xhr'),因为JS undefined被视为false,之后我检查了data('xhr')是否abort } attribute。

顺便说一句,如果你想在按下键时停止计时器,最好只清除超时,它不会运行AJAX调用,所以不需要将XHR对象放到元素的数据存储中:

if($(this).data('timer')) {
  clearTimeout($(this).data('timer'));
}

var timer = setTimeout(function() {
    $.ajax({
        url :  '/files/tags_autocomplete.php',
        dataType : 'JSON',
        success : function (tags) {
          $("ul").html(tags.output);
        }
    });
}, 500);

$(this).data('timer', timer);

甚至更简单(没有数据存储):

if(window.autocompleteTimer) {
  clearTimeout(window.autocompleteTimer);
}

window.autocompleteTimer = setTimeout(function() {
    $.ajax({
        url :  '/files/tags_autocomplete.php',
        dataType : 'JSON',
        success : function (tags) {
          $("ul").html(tags.output);
        }
    });
}, 500);

答案 1 :(得分:2)

这里的问题是undefined值没有任何属性。您需要检查data()的返回值,以检查它是否未定义。

var xhr = $(this).data('xhr');
if(typeof xhr !== 'undefiend' && xhr.abort) {
    // do your code here
}

将您的if语句替换为上述4行代码。

答案 2 :(得分:1)

问题是如果用户在500ms之前再次输入,$(this).data('xhr')将是未定义的,因为它尚未设置为ajax请求。

由于我们无法在in上使用undefined运算符,仅在对象上,清除超时和中止任何待处理请求的正确解决方案是检查是否{{1已经设置,并且是一个对象,然后检查它是否具有$(this).data('xhr')属性

abort