我正在构建一个面板,用户在其中添加贡献者的详细信息,然后输入该贡献者的一个或多个博客的数据。
每个博客都是通过使用JSONP的api调用添加到数据库中的。(请求中需要JSONP回调函数名。)因此,当用户单击AddBlog按钮时,就会调用AddBlog函数——这会进行一些客户端验证并发送ajax请求。它还将ajax请求添加到一个数组中。
回调函数cbAddBlog根据服务器返回的任何错误进行更多验证。
因此,当所有博客都被添加后,我想显示一条消息,让用户知道博客已经保存,并重置表单。
问题是回调函数(cbAddBlog)是在$when..中的代码之后执行的
当您有一个定义的回调函数时,$.when与JSONP一起工作吗?或者我的代码有其他问题吗?我需要在回调函数中实现Deferred吗?
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
我看到了同样的问题(即使只有一个博客,回调也会在$.之后执行。
$.when()
不接受数组作为参数,它需要一个或多个promise作为单独的参数。因此,如果您有一个数组,则需要使用.apply()
将该数组转换为单独的参数。更改此项:
$.when(addBlogCalls)
到此:
$.when.apply($, addBlogCalls)
似乎您对JSONP回调的所有覆盖都阻止了jQuery处理结果,因此它无法解析promise,因此$.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);
}