为什么我的例外没被抓住?

时间:2014-11-18 04:25:45

标签: javascript jquery

我正在编写一个jQuery插件,允许用户添加对他们文章的引用。基本上,当用户专注于引用输入时按下回车键,脚本会通过我的AJAX脚本检查URL,以确保它是一个有效的URL。如果它有效,则会将一个按钮添加到用户可以看到的引用列表中。它还将更新包含以逗号分隔的URL列表的隐藏输入。

我对JS异常的概念很新...我目前收到错误说Uncaught [object Object].错误发生在我抛出变量' info'。有什么想法吗?

(function($){
    $.fn.extend({
        references : function(options) {
            var defaults = {
                sample_div : '#sample-ref',
                remove_button : '#removereference',
                update_div : '#references',
                hidden_input : 'input[name="references"]',
                saved_input : 'input[name="saved-refs"]',
                ajax_url : 'ajax.php',
                search_input : '#reference'
            };        
            var options = $.extend(defaults, options);
            var count = 0;
            function addReferenceBlock(ref_title){
                var replacements = {
                    ref_title : ref_title,
                    ref_url : ref_url
                };
                var block = $(options.sample_div).html();
                $.each(replacements, function(index, value){
                    block.replace(new RegExp('{'+index+'}', 'g'), value);
               });
               $(options.update_div).append(block);
            }
            function checkReference(url){
                var postData = 'reference='+url;
                $.ajax(
                {
                    dataType: "xml",
                    type: "POST",
                    data : postData,
                    cache: false,
                    url: options.ajax_url
                })
                .done(function(xml, textStatus, jqXHR){
                    if(textStatus === 'success'){
                        $(xml).find('success').each(function(){     
                            console.log('checking '+url+'...');
                            var info = $(this).find('pagetitle');
                            throw info;
                        });
                        $(xml).find('error').each(function(){
                            throw false;
                            console.log($(this).find('message').text());
                        });
                    } else {
                        console.log(jqXHR);
                    }
                });
            }
            function init(element, options){
                $(options.search_input).enterKey(function(e){
                    try {
                        checkReference($(options.search_input).val());
                    } catch($status){
                        if($status !== false){
                            addReferenceBlock($status);
                            updateReferenceInput($(options.search_input).val());
                        } else {
                            alert($status);
                        }
                    }
                    e.preventDefault();
                });
            }
            return $(this).each(function(){ init(this, options); });
        }
    });
})(jQuery);

2 个答案:

答案 0 :(得分:3)

您的try阻止了checkReference功能。您的checkReference函数调用了donedone 会调用引发错误的匿名函数;它设置了一个事件处理程序,以便稍后系统可以调用它。因此,您的堆栈跟踪不是您认为的那样。

修改

  

为什么"完成"不调用它里面的代码?

因为如果确实如此,那就不是异步的。让我们用setTimeout而不是AJAX来嘲笑它,同样的原则适用:



function foo(how) {
  throw("In foo " + how + " (look at the stack trace by clicking on the triangle)");
}

function callFooAsynchronously() {
  console.log("calling foo asynchronously");
  setTimeout(function() {
    foo("asynchronously");
  }, 1000);
  console.log("finished calling foo asynchronously");
}

function callFooSynchronously() {
  console.log("calling foo synchronously");
  foo("synchronously");
  console.log("finished calling foo synchronously");
}

function main() {
  callFooAsynchronously();
  callFooSynchronously();
}

main();




输出如下:

calling foo asynchronously js:18
finished calling foo asynchronously js:22
calling foo synchronously js:26
Uncaught In foo synchronously (look at the stack trace by clicking on the triangle) js:14
  foo js:14
  callFooSynchronously js:27
  main js:34
  (anonymous function) js:37
Uncaught In foo asynchronously (look at the stack trace by clicking on the triangle) js:14
  foo js:14
  (anonymous function)

同步调用将启动,然后抛出异常。由于例外,"同步调用foo"永远不会显示。堆栈跟踪显示来自代码段执行环境的调用,调用main,调用callFooSynchronously,最终调用foo

异步调用将显示启动消息,附加超时处理程序,然后显示已完成的消息,然后退出。结论为callFooAsynchronously。一秒钟之后,浏览器会记住它需要做的事情,这反映在堆栈跟踪中:传递给setTimeout的匿名函数运行,然后运行foo。请注意maincallFooAsynchronously不是堆栈跟踪的一部分:它们设置了警报,然后离开了建筑物。 callFooAsynchronously,尽管名称如此,但从不拨打foosetTimeout也没有。

浏览器直接调用setTimeout中的匿名函数,就像它直接调用onreadystatechange上的XMLHttpRequest函数一样(最终调用传递给{{1}的函数的函数} {},附加,但名为done

如果jQuery.ajax调用了您的函数,它将在您进行done调用后立即执行,而不是在响应到达时执行,因为这是ajax执行的时间。

答案 1 :(得分:-1)

在JS中,您可以使用错误字符串抛出错误,例如:throw new Error('You did something wrong')

因此,在您的情况下,也许您可​​以尝试:throw new Error(info.text()),它将获取.pagetitle元素中的文本。

这是你想要的吗?