我正在构建一个仪表板,用户可以在其中添加贡献者详细信息,然后为该贡献者输入一个或多个博客的数据。
使用JSONP通过api调用将每个博客添加到数据库中。 (请求中需要JSONP回调函数名。)因此,当用户单击Add Blog按钮时,将调用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
我看到了同样的问题(即使只有一个博客,也会在$。之后执行回调..
答案 0 :(得分:0)
$.when()
不接受数组作为参数,它需要一个或多个promise作为单独的参数。因此,如果您有一个数组,则需要使用.apply()
将该数组转换为单个参数。改变这个:
$.when(addBlogCalls)
到此:
$.when.apply($, addBlogCalls)
似乎所有重写JSONP回调都会阻止jQuery处理结果,因此它无法解决承诺,因此$.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);
}