Javascript 在使用定义了回调函数的JSONP时使用$
我正在构建一个仪表板,用户在其中添加贡献者详细信息,然后为该贡献者的一个或多个博客输入数据 每个博客都通过使用JSONP的api调用添加到数据库中。(请求中需要JSONP回调函数名。)因此,当用户单击AddBlog按钮时,将调用AddBlog函数——这将执行一些客户端验证并发送ajax请求。它还将ajax请求添加到数组中 回调函数cbAddBlog根据服务器返回的任何错误执行更多验证 因此,当所有的博客都被添加后,我想显示一条消息,让用户知道博客已经保存,并重置表单 问题是回调函数(cbAddBlog)在代码之后执行,单位为$。when 当您有一个已定义的回调函数时,$.when是否使用JSONP?还是我的代码有其他问题?我需要在回调函数中实现Deferred吗Javascript 在使用定义了回调函数的JSONP时使用$,javascript,jquery,jsonp,jquery-deferred,.when,Javascript,Jquery,Jsonp,Jquery Deferred,.when,我正在构建一个仪表板,用户在其中添加贡献者详细信息,然后为该贡献者的一个或多个博客输入数据 每个博客都通过使用JSONP的api调用添加到数据库中。(请求中需要JSONP回调函数名。)因此,当用户单击AddBlog按钮时,将调用AddBlog函数——这将执行一些客户端验证并发送ajax请求。它还将ajax请求添加到数组中 回调函数cbAddBlog根据服务器返回的任何错误执行更多验证 因此,当所有的博客都被添加后,我想显示一条消息,让用户知道博客已经保存,并重置表单 问题是回调函数(cbAddB
var errorState = false,
contributorId = '23',
addBlogCalls = [];
$("#btnAddBlog").click(function (e) {
$('#add_contributor section.blog').each(function () { //call addBlog for each of the users blogs
addBlog(contributorId, $(this).attr('id'));
});
$.when.apply($, addBlogCalls).done(function () {
console.log("WHEN + errorState: " + errorState); //This is output to console BEFORE the line in the cbAddBlog callback function
});
e.preventDefault();
});
addBlog : function (contributorId, blogSection) {
//client side validation - following is excecuted if there are no errors
addBlogCalls.push(
$.ajax({
url : (apiRoot + "f=jsonp").trim(),
dataType : 'jsonp',
jsonp : false,
jsonpCallback : "cbAddBlog",
fail: function (e) {
console.log("error function");
console.log(e.message);
},
done: function (e) {
console.log("done function");
console.log(e.message);
}
})
);
console.log("Added to addBlogCalls array");
console.log(addBlogCalls);
}
cbAddBlog : function (data) {
console.log("cbAddBlog data.result: " + data.result); //Printed to console AFTER line from $.when ??
//code to check if there are any errors returned from server and display them to user
}
控制台的输出:
Added to addBlogCalls array
[Object { readyState=1, setRequestHeader=function(), getAllResponseHeaders=function(), more...}]
Added to addBlogCalls array
[Object { readyState=1, setRequestHeader=function(), getAllResponseHeaders=function(), more...}, Object { readyState=1, setRequestHeader=function(), getAllResponseHeaders=function(), more...}]
WHEN + CD.config.errorState: false
cbAddBlog data.result: 1
cbAddBlog data.result: 1
我看到了同样的问题(回调在$之后执行。即使只有一个blog….$。当()
不接受数组作为参数时,它需要一个或多个承诺作为单个参数。因此,如果有数组,则需要使用.apply()
将该数组转换为单个参数。更改此选项:
$.when(addBlogCalls)
为此:
$.when.apply($, addBlogCalls)
另外,您对JSONP回调的所有重写似乎都在阻止jQuery处理结果,因此它无法解析承诺so
$.when()
不起作用。由于您现在已将服务器更改为接受callback=fname
,因此这更容易,因为您可以删除所有特殊的JSONP处理,并让jQuery执行它想要执行的操作。您的代码也可以被清理,以便不依赖未重新初始化的全局变量来执行后续操作
我推荐如下:
$("#btnAddBlog").click(function (e) {
var addBlogCalls = $('#add_contributor section.blog').map(function () { //call addBlog for each of the users blogs
return addBlog(contributorId, $(this).attr('id'));
}).toArray();
$.when.apply($, addBlogCalls).done(function () {
console.log("WHEN + errorState: " + errorState); //This is output to console BEFORE the line in the cbAddBlog callback function
});
e.preventDefault();
});
addBlog : function (contributorId, blogSection) {
//client side validation - following is excecuted if there are no errors
return $.ajax({
url : (apiRoot + "f=jsonp").trim(),
dataType : 'jsonp'
}).done(cbAddBlog);
}
谢谢你-非常感谢-我已经在我的代码中更新了它。但是现在它根本不执行when部分中的代码。这可能与这是JSONP这一事实有关吗?我在其他地方对JSON调用使用了类似的代码,它工作得很好-一旦调用完成,它将以$when执行代码。@user1492058-In一般来说,为jQuery JSONP调用指定自己的回调函数是一件坏事,因为您正在将jQuery从响应循环中删除,因此它无法执行接收响应时通常执行的操作(例如解析承诺或调用完成回调)。因此,这可能就是您没有得到任何已解决承诺的原因。@user1492058-jQuery文档的这一部分不是很清楚,但是如果您的服务器在URL中要求
cb=xxx
,而不是callback=xxx
,那么应该有一种方法告诉jQuery只更改回调参数的名称,但仍然让它提供自己的函数,这样它就可以完成所有正常的响应处理。从阅读文档(在这方面写得很糟糕)中,我的第一个猜测是,您可以为$.ajax()设置jsonp:'cb'
选项
,从URL中取出cb=cbAddBlog
,然后在正常的jQuery位置处理ajax响应,可能在$的末尾。when()
。谢谢你。我刚刚从文档(api.jQuery.com/jQuery.ajax)中更新了上面的代码听起来我需要将jsonp设置为false,并在jsonpCallback参数中添加函数名。它仍然不起作用。响应包装在一个名为“callback”的函数中返回,并且在ajax中没有到达fail或done函数。在$结尾添加回调代码。什么时候不起作用?我只想以$为单位的代码。当所有addBlog调用完成时将在何时执行-可能有多个调用为参与者添加博客数据..@user1492058-我不确定您是否理解我所描述的问题。如果您为JSONP调用提供自己的回调函数(您正在这样做),然后jQuery不处理响应。不调用ajax回调,不解决任何承诺。jQuery甚至从未被告知响应。因此,jQuery对响应没有任何功能。您必须自己完成所有操作。