首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >coldfusion cfajaxproxy回调处理程序调用次数过多

coldfusion cfajaxproxy回调处理程序调用次数过多
EN

Stack Overflow用户
提问于 2012-12-20 03:19:31
回答 1查看 586关注 0票数 3

我是使用cfajaxproxy的新手,我正在尝试选择一些复选框,然后循环所有选中的复选框,并使用cfajaxproxy和jQuery将结果保存在数据库中。

该标记是通过遍历查询生成的,但以下是一个给我带来问题的区域的示例:

代码语言:javascript
复制
<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>

下面是我的cfajax代理标记:

代码语言:javascript
复制
<cfajaxproxy cfc="#APPLICATION.cfMapping#.Agency.Agency" 
jsclassname="agency_object">

下面是它应该在每个复选框上运行的函数:

代码语言:javascript
复制
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
  );
}

下面是遍历每个选中框的jQuery代码:

代码语言:javascript
复制
$("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的方法是:

代码语言:javascript
复制
<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次。我检查了所有7个框,cfc方法被调用了19次。

我的第一个想法是也许cfc被调用了正确的次数,但是回调处理程序被调用了很多,因为每个实例在返回结果时都会调用它的响应处理程序,所以我创建了一个agency_object的全局实例,每次得到相同的结果时都会调用该方法。

有人知道为什么会发生这种情况吗?

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-26 22:35:54

“因为回调处理程序不知道它应该处理哪个特定的响应,所有回调处理程序都处理所有响应”

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

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

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

代码语言:javascript
复制
saveResponses(...){

  //...

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

  //...

}

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

  • 第一次调用它时,您有一个处理程序和一个结果。
  • 第二次调用它时,您添加了一个处理程序(2个处理程序),因此您的1个结果被处理了两次。
  • 第三次调用它时,您添加了第三个处理程序,因此1个结果处理了3次。

由于.each()方法,saveResponse被多次调用;它快速连续地循环遍历jQuery选择器返回的每个项,为每个项运行一次每个处理程序函数。

这加起来只有6个调用,所以仍然有一些不正确的地方,但你可以看到这很快就会成为一个大问题。第7个可能是因为ajax请求的异步特性。实际发生的情况可能更像是:

  • saveResponses调用了
    1. 添加回调处理程序
    2. 发送ajax request

  • saveResponses调用了
    1. 添加回调处理程序
    2. 发送ajax request

返回第一个请求的

  • 结果。有两个处理程序,所以它被发送到这两个处理程序。到目前为止看到的
  • 2回调从第二个请求返回
  • 结果。2个处理程序,发送给这两个处理程序。far
  • saveResponses看到了4个回调,因此request

调用了

  • 添加回调处理程序

  • 发送ajax处理程序

来自第三个请求的

  • 结果返回。3个处理程序,发送给所有3个。到目前为止看到的
  • 7回调

教训:在调用者之外声明/分配处理程序(在类的实例化位置附近最有意义)。

如果您真的想了解JavaScript --您应该这样做--请选择一本JavaScript: The Good Parts。它非常简短,但写得非常好,使复杂的概念更容易理解。其中一些在你目前的技能水平上可能没有多大意义,但首先要关注那些触手可及的东西(例如匿名函数),然后在你真正摸索它们之后,继续做更难的事情,比如模块。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13959566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档