Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在使用定义了回调函数的JSONP时使用$_Javascript_Jquery_Jsonp_Jquery Deferred_.when - Fatal编程技术网

Javascript 在使用定义了回调函数的JSONP时使用$

Javascript 在使用定义了回调函数的JSONP时使用$,javascript,jquery,jsonp,jquery-deferred,.when,Javascript,Jquery,Jsonp,Jquery Deferred,.when,我正在构建一个仪表板,用户在其中添加贡献者详细信息,然后为该贡献者的一个或多个博客输入数据 每个博客都通过使用JSONP的api调用添加到数据库中。(请求中需要JSONP回调函数名。)因此,当用户单击AddBlog按钮时,将调用AddBlog函数——这将执行一些客户端验证并发送ajax请求。它还将ajax请求添加到数组中 回调函数cbAddBlog根据服务器返回的任何错误执行更多验证 因此,当所有的博客都被添加后,我想显示一条消息,让用户知道博客已经保存,并重置表单 问题是回调函数(cbAddB

我正在构建一个仪表板,用户在其中添加贡献者详细信息,然后为该贡献者的一个或多个博客输入数据

每个博客都通过使用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
我看到了同样的问题(回调在$之后执行。即使只有一个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对响应没有任何功能。您必须自己完成所有操作。