繁体   English   中英

AJAX —多个并发请求:延迟AJAX执行,直到某些调用完成

[英]AJAX — Multiple concurrent requests: Delay AJAX execution until certain calls have completed

我目前正在开发基于Web的时间跟踪软件 我正在学习grails,但是这个问题仅与javascript和异步请求有关。

时间跟踪工具应使用户能够选择当月的一天,每天 创建一个或多个活动,保存一整天 必须将每个活动分配给一个项目和一个合同。

选择“保存”后,将部分工作日保存到数据库中,计算小时数,并在页面底部更新表格,以显示用户每月工作时间的概览。

现在到我的问题:可能有很多AJAX请求。 病人用户可能只单击一次“创建活动”按钮,然后等待其创建。 但是,其他人可能会一直单击直到发生某件事。

这里的主要问题是更新视图 ,尽管由于并发数据库事务(尤其是依次选择“保存”和“删除”时),我也认识到一些失败的调用。 关于该问题的任何反馈-请求不“等待”同一行再次准备就绪-也将很感激,但这不是我的问题。

我有一个updateTemplate(data, day)函数,该函数在我的函数saveRecord()deleteRecord()pasteRecords()makeEditable()的相应ajax调用的onSuccess上调用(撤消保存)。 这是jquery中的AJAX调用示例:

$.ajax({
    type: "POST",
    url: "${g.createLink(controller:"controller", action:"action")}",
    data: requestJson,
    contentType:"application/json; charset=utf-8",  
    async: true,
    success: function(data, textstatus) {updateTemplate(data["template"], tag); updateTable(data["table"]);},
}); 

在控制器操作中,将JSON对象呈现为响应,其中包含键templatetable 每个键都有一个模板,使用g.render渲染为分配给它的字符串。

现在,当我在很短的间隔内重复单击create时,由于异步调用,会发生一些同时执行的create (或其他)动作。 问题是updateTemplate只是从响应中渲染数据; 要呈现的数据在create controller动作中收集。 但是“最后一个”请求操作只能找到由其自身创建的对象。 认为这是因为create动作是同时运行的

我发现在处理动态刷新的页面时,有些事情我要么过于复杂,要么做的本质上是错误的。 我发现唯一可以帮助您的是同步调用,它可以工作,但用户体验却很糟糕。 我必须采取哪些选择措施才能完成这项工作? 这是真的吗?还是我只是在寻找错误的方法? 我该如何使它们更加健壮,以使不耐烦的用户无法破坏我的代码?

*********编辑:********

我知道我可以阻止按钮或键盘快捷键,使用同步呼叫或类似方法来避免这些问题。 但是,我想知道是否有可能通过提交多个AJAX请求来解决它。 因此,用户将能够继续添加新活动,尽管它们不会立即出现。 无论如何,都有一个微调器用于反馈。 我只是想以某种方式确保在触发“最后一个” AJAX请求之前,数据库是最新的,以便控制器操作将使用具有正确对象的最新gsp模板进行响应

这个Stackoverflow答案的帮助下,我找到了一种确保ajax调用(在最后执行的javascript函数中)始终以最新模型响应的方法。 基本上,如果之前已经启动但尚未完成“关键” AJAX请求,则将包含AJAX调用的javascript函数放在等待队列中。

为此,我定义了函数doCallAjaxBusyAwareFunction(callable) ,该函数在执行callable函数之前检查全局变量Global.busy是否为'true'。 如果为true,则该函数将再次执行,直到Global.busyfalse为止,以最终执行该函数(从DOM收集数据)并触发AJAX请求。

全局变量的定义:

var Global = {
    ajaxIsBusy = false//,
    //additional Global scope variables
};

函数doCallAjaxBusyAwareFunction定义:

function doCallAjaxBusyAwareFunction(callable) {
        if(Global.busy == true){
           console.log("Global.busy = " + Global.busy + ". Timout set! Try again in 100ms!!");  
           setTimeout(function(){doCallAjaxBusyAwareFunction(callable);}, 100);
        }     
        else{                
            console.log("Global.busy = " + Global.busy + ". Call function!!");   
            callable();             
        }
    }

为了将包含ajax的功能标记为关键,我让它从一开始就设置Global.busy = true ,在AJAX完成时设置Global.busy = false 示例调用:

function xyz (){
    Global.busy = true;
    //collect ajax request parameters from DOM

    $.ajax({
        //desired ajax settings
        complete: function(data, status){ Global.busy = false; }
    }

由于从一开始Global.busy设置为true,因此无法操作DOM,例如在函数xyz收集DOM数据时通过delete s进行操作。 但是当函数执行后,在ajax调用完成之前,仍然存在Global.busy === true

从“忙碌感知”功能触发ajax调用:

doCallAjaxBusyAwareFunction(function(){
    //collect DOM data

    $.ajax({/*AJAX settings*/});
});

....或从“忙碌感知”功能触发ajax调用,该功能本身也被标记为关键(基本上是我主要使用的功能):

doCallAjaxBusyAwareFunction(function(){
    Global.busy = true;
    //collect DOM data

    $.ajax({
        //AJAX SETTINGS
        complete: function(data, status){ Global.busy = false; }
    });
});

欢迎提供反馈和其他选择,尤其是如果此方法不好的话。 我真的希望有人能找到这篇文章并对其进行评估,因为我根本不知道是否应该这样做。 我暂时不会回答这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM