使用JQuery延迟进度和通知方法的前端/后端技术

使用JQuery延迟进度和通知方法的前端/后端技术,jquery,ajax,Jquery,Ajax,在我的网站上,我有一个按钮供用户点击,上面写着“同步对象”。按下此按钮将调用我的服务器来启动一个进程,在该进程中,我调用外部系统来获取所有用户对象,并将每个对象保存到我的数据库中。在这种情况下,我想让用户知道到目前为止有多少对象已经同步 这似乎是JQuery的notify和progress方法的正确用例,我以前从未使用过这些方法 我的第一个想法是: 创建一个ajax来启动同步过程,返回promise A。在该过程启动后,我进行一个单独的ajax调用,每2秒向一个单独的端点返回promise B,

在我的网站上,我有一个按钮供用户点击,上面写着“同步对象”。按下此按钮将调用我的服务器来启动一个进程,在该进程中,我调用外部系统来获取所有用户对象,并将每个对象保存到我的数据库中。在这种情况下,我想让用户知道到目前为止有多少对象已经同步

这似乎是JQuery的
notify
progress
方法的正确用例,我以前从未使用过这些方法

我的第一个想法是:

创建一个ajax来启动同步过程,返回promise A。在该过程启动后,我进行一个单独的ajax调用,每2秒向一个单独的端点返回promise B,该端点返回该用户当前数据库中的对象总数。我使用该值更新显示给用户的总同步计数

这似乎不是正确的方法,因为我基本上将同步过程和进度检查视为两个独立的承诺


如何正确使用JQuery的
notify
progress
方法让用户不断了解同步作业的进度?

注意,利用下面的模式,可以将
dfd.progress(fn)
部分包装到web worker消息事件中,该事件由对服务器的调用启动,在检索和处理对象期间从服务器发回页面的消息

试一试

html

同步对象
js

//调用外部系统以获取所有用户对象,
//`requests`:users对象
var请求=[1,2,3,4,5,6,7,8,9,10];
//将用户对象保存到数据库,`uo`
var uo=[];
//文本通知
var pgx=$(“div”);
//`进度'要素通知
风险值进度=$(“进度”);
//将'progress``max`设置为'requests``长度`
attr({“max”:requests.length,“value”:0});
//jquery`deferred`对象
var dfd=新的$.Deferred();
//做一些进步的事情
dfd.进度(功能(msg){
$(this.html(msg+“已处理对象”);
progress.get(0).value=uo.length;
if(uo.length==requests.length){
//在所有“请求”完成时解析“dfd”
dfd.解决方案(uo)
}
});
//当所有“uo”被检索、处理时做一些事情
dfd.done(功能(数据){
pgx.append(“
”+JSON.stringify(数据,null,4)) }); $(“按钮”)。在(“单击”)上,函数(e){ $.each(请求、函数(键、值){ //调用服务器以启动进程 setTimeout(函数(){ $.post(“/echo/json/” , { json:json.stringify(值) }) .always(函数(数据、文本状态、jqxhr){ 如果(textStatus!=“成功”){ //处理“错误”响应 console.log(textStatus,jqxhr) }否则{ //将“用户对象”`data`保存到“数据库”`uo` uo.推送(数据); //通知已完成的对象检索、处理、, //使用'pgx'作为'dfd'上下文 dfd.notifyWith(pgx,[uo.length]) } }) },键*Math.floor(Math.random()*2000)) }) });

jsfiddle

如果不实现某种websocket解决方案,您的方法基本上是正确的。唯一的问题是,如果您使用“外部系统”来保存每个用户对象,那么客户机将不知道这些位何时被成功添加。为了实现进度指标,我认为您需要从JS中发布每个用户对象,并利用回调。
<button>Sync Objects</button>
<progress></progress>
<div></div>
// call an external system to get all of the users objects , 
// `requests` : users objects
var requests = [1,2,3,4,5,6,7,8,9,10];
// save user objects to database , `uo`
var uo = [];
// text notification 
var pgx = $("div");
// `progress` element notification
var progress = $("progress");
// set `progress` `max` to `requests` `length`
progress.attr({"max":requests.length, "value":0});
// jquery `deferred` object
var dfd = new $.Deferred();
// do progress stuff
dfd.progress(function(msg) {
  $(this).html(msg + " objects processed");
  progress.get(0).value = uo.length; 
    if (uo.length === requests.length) {
      // resolve `dfd` when all `requests` complete
      dfd.resolve(uo)
    }
});
// do stuff when all `uo` retrieved , processed
dfd.done(function(data) {
  pgx.append("<br><pre>" + JSON.stringify(data, null, 4))
});

$("button").on("click", function(e) {
    $.each(requests, function(key, value) {
        // call server to initiate a process
        setTimeout(function() {
            $.post("/echo/json/"
                   , {
                       json:JSON.stringify(value)
            }) 
            .always(function(data, textStatus, jqxhr) {
                if (textStatus !== "success") {
                  // handle `error` response
                  console.log(textStatus, jqxhr)
                } else {
                  // save "user object" `data` to "database" `uo`
                  uo.push(data);
                  // notify completed object retrievals , processing ,
                  // with `pgx` as `dfd` context
                  dfd.notifyWith(pgx, [uo.length])
                }
            })
         }, key * Math.floor(Math.random() * 2000))            
    })
});