我正在编写一个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);
答案 0 :(得分:3)
您的try
阻止了checkReference
功能。您的checkReference
函数调用了done
。 done
不会调用引发错误的匿名函数;它设置了一个事件处理程序,以便稍后系统可以调用它。因此,您的堆栈跟踪不是您认为的那样。
修改强>
为什么"完成"不调用它里面的代码?
因为如果确实如此,那就不是异步的。让我们用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
。请注意main
和callFooAsynchronously
不是堆栈跟踪的一部分:它们设置了警报,然后离开了建筑物。 callFooAsynchronously
,尽管名称如此,但从不拨打foo
,setTimeout
也没有。
浏览器直接调用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元素中的文本。
这是你想要的吗?