Jquery 调用coldfusion cfajaxproxy回调处理程序的次数太多

Jquery 调用coldfusion cfajaxproxy回调处理程序的次数太多,jquery,ajax,coldfusion,cfajaxproxy,Jquery,Ajax,Coldfusion,Cfajaxproxy,我对使用cfajaxproxy还不熟悉,我正在尝试选择一些复选框,然后循环检查所有复选框,并使用cfajaxproxy和jQuery将结果保存在数据库中 标记是通过循环查询生成的,但下面是一个给我带来问题的区域示例: <span id="1569_2627_text">I certify that the employee has been trained in the use of the following equipment (please check all that ap

我对使用cfajaxproxy还不熟悉,我正在尝试选择一些复选框,然后循环检查所有复选框,并使用cfajaxproxy和jQuery将结果保存在数据库中

标记是通过循环查询生成的,但下面是一个给我带来问题的区域示例:

<span id="1569_2627_text">I certify that the employee has been trained in the use of the following 
equipment (please check all that apply):</span><br />

<input type="hidden" name="2627_max_length" id="2627_max_length" value="">
<input type="hidden" name="2627_min_value" id="2627_min_value" value="">
<input type="hidden" name="2627_max_value" id="2627_max_value" value="">
<input type="hidden" name="2627_regex_format" id="2627_regex_format" value="">
<input type="hidden" name="2627_system_type" id="2627_system_type" value="">
<input type="hidden" name="2627_app_type_version" id="2627_app_type_version" value="1569">
<input type="hidden" name="2627_question_type" id="2627_question_type" value="CM">


<label>
    <input class="questionChoice" type="checkbox" name="2627" 
    value="8509" data-app_type_version="1569">
        <span>Face Shield<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627" 
    value="8510" data-app_type_version="1569">
        <span>Neoprene Gloves<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8511" data-app_type_version="1569">
        <span>Apron<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8512" data-app_type_version="1569">
        <span>Boots<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8513" data-app_type_version="1569">
        <span>Wizard Glove<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8514" data-app_type_version="1569">
        <span>Insulated Mitt<span>
</label><br />

<label>
    <input class="questionChoice" type="checkbox" name="2627"
    value="8515" data-app_type_version="1569">
        <span>Insulated Glove<span>
</label><br />

<button class="add_answer" value="2627" data-app_type_version="1569" disabled>Add answer</button>
下面是循环通过每个复选框的jQuery代码:

function saveResponses(question_no, answerValue){

  var myagOBJ = new agency_object();
  myagOBJ.setHTTPMethod('POST');
  myagOBJ.setCallbackHandler(function(result) {
    numOfCalls++;
    alert(result+ ", call number: "+ numOfCalls);   
  });   
  myagOBJ.setErrorHandler(null);

  myagOBJ.store_prepopulated_response(
     agency_id = #SESSION.agency_object.get_id()#,
     jQuery("select##site").val(),
     question_no,
     answerValue
  );
}
$("div##" + div + " [name=" + question_no + "]:checked").each(function() {
    answerText = $(this).next().text();
    answerValue = $(this).val();
    identifier = question_no + "_" + answerValue;
    if(answers["q_" + identifier] ===  undefined) {
    formAppend();
    answers["q_" + identifier] = answerValue;
    alert("From Checkbox");
    saveResponses(question_no, answerValue);
    $("div##saved_answers table").append(
        "<tr id=\"" + identifier + "\"><td><strong>" + formName + 
        "</strong><br>" + questionText + "</td><td>" + answerText + 
        "<br><button data-app_type_version=\"" + div + 
        "\"class=\"remove\" value=\"" + identifier + 
        "\">Remove</button></td></tr>"
    );
    }
});
它调用的cfc的方法是:

<cffunction name="store_prepopulated_response" access="remote" returntype="string" verifyclient="true">
<cfargument name="agency_id" type="numeric" required="true">
<cfargument name="site_id" type="numeric" required="true">
<cfargument name="question_no" type="numeric" required="true">
<cfargument name="response" type="string" required="true">



<cfreturn "Agency id: #agency_id#, Site ID: #site_id#, Question No: #question_no#, Resonse: #response#">
</cffunction>
我仍然只是在测试一些东西,以确保它能正常工作,所以很多函数实际上除了返回测试结果之外什么都做

当我运行这段代码时,它调用cfc很好,并返回结果,但是它调用它的次数太多了

例如,如果我选中三个框,它将调用cfc方法7次,如果我选中两个框,它将调用cfc方法5次。我选中了cfc方法调用19次的所有7个框

我的第一个想法是,可能cfc被调用的次数正确,但是callbackhandler被调用的次数太多,因为当返回结果时,每个实例都将调用其响应处理程序,所以我创建了agency_对象的一个全局实例,每次都调用这个方法,但是得到了相同的结果

有人知道为什么会这样吗

*编辑我刚刚用一个调用计数向实际的cfc添加了一个计数,实际上它调用cfc方法的次数太多了

因为callbackhandler不知道它应该处理哪个特定响应,所有这些响应都会处理所有响应

回调处理程序就是这样工作的。他们应该处理所有的回应。问题是您正在创建多个回调处理程序,它们都做相同的事情;每个响应都被发送到每个处理程序

通过使用JavaScript匿名函数将函数{…}作为方法参数传递给saveResponses函数,在saveResponses函数中设置处理程序,可以为该类附加其他回调处理程序。如果您正在为每个请求创建和销毁对象,那么这可能是有意义的,但是正如在您的帖子的评论中所讨论的,您最好创建一个实例。使用这种方法,您还应该将回调处理程序设置在此函数之外

为了说明发生了什么,让我们看看当您选中3个框并运行saveResponses时会发生什么:

附加处理程序解释了3个复选框->7个调用

第一次调用它时,有1个处理程序和1个结果。 第二次调用它时,您添加了一个处理程序2个处理程序,因此您的1结果将被处理两次。 第三次调用时,添加了第三个处理程序,因此1个结果处理了3次。 saveResponse被多次调用,因为.each方法;它快速连续地循环jQuery选择器返回的每个项目,为每个项目运行一次each handler函数

这总共只有6个电话,所以有些地方仍然不对劲,但你可以看到这将很快成为一个巨大的问题。第七种可能是因为ajax请求的异步性质。真正发生的事情可能更像:

saveResponses呼叫 添加回调处理程序 发送ajax请求 saveResponses呼叫 添加回调处理程序 发送ajax请求 返回第一个请求的结果。有2个处理程序,因此它被发送到这两个处理程序。 迄今为止已看到2次回调 返回第二个请求的结果。2个处理程序,发送给两个。 到目前为止已看到4次回调 saveResponses呼叫 添加回调处理程序 发送ajax请求 返回第三个请求的结果。3个处理程序,发送给所有3个。 到目前为止已看到7次回调 教训:在类实例化位置附近的调用方外部声明/分配处理程序最有意义


如果你真的想学习JavaScript——你应该——拿起一本JavaScript:好的部分。它很短,但写得非常好,使复杂的概念更容易理解。在你目前的技能水平上,其中一些可能没有多大意义,但首先要关注那些可以实现的功能,例如匿名函数,然后在你真正尝试了这些功能之后,再转向更难的事情,比如模块。

你发布的jquery代码是如何/何时调用的?点击某个按钮?单击每个复选框?您确定您的saveResponses函数没有从代码中的任何其他位置调用吗?此外,尽管不相关,但您的代码正在为每个选中的复选框创建新代理对象的新实例-这是不必要的;只需在saveResponses函数之外创建它的一个实例,然后调用它的store\u prepopulated\u response方法,这就是我最后要做的。这个问题仍然存在,但我确实发现cfc方法实际上并没有一直被调用,只有回调处理程序才被调用。因为callbackhandler不知道它应该处理哪个特定响应,所以所有这些响应都会处理所有响应。
<cffunction name="store_prepopulated_response" access="remote" returntype="string" verifyclient="true">
<cfargument name="agency_id" type="numeric" required="true">
<cfargument name="site_id" type="numeric" required="true">
<cfargument name="question_no" type="numeric" required="true">
<cfargument name="response" type="string" required="true">



<cfreturn "Agency id: #agency_id#, Site ID: #site_id#, Question No: #question_no#, Resonse: #response#">
</cffunction>
saveResponses(...){

  //...

  myagOBJ.setCallbackHandler(function(result) {
    numOfCalls++;
    alert(result+ ", call number: "+ numOfCalls);   
  });

  //...

}