强制jQuery的递延等到阿贾克斯完成"然后"处理器处理器、递延、jQuery、QUOT

2023-09-10 14:49:45 作者:如果当时╮你不走

我有情况,我相信我需要创建一个再处理一个Deferred对象,但等到,然后处理程序,在移动之前完成它自己的承诺。

I have situation where I believe I need to create a Deferred object with a "then" handler, but wait until the "then" handler has completed it's own promise before moving on.

用例是一个创纪录的对象,而上述功能是它的保存方法。该记录对象有一个名为saveQueue的属性,这是对记录的实例设置为$ .Deferred()。在saveQueue的决心,呼吁应该确保递延总是有执行的每一个新的处理程序连接到它,只要它可以。这个想法是,你可以调用多次保存在短时间内连续记录,但通话将运行一个接一个,而不是重叠。

The use case is a record object, and the above function is it's save method. The record object has an attribute called saveQueue, which is set to $.Deferred() on the record's instantiation. The resolve call on saveQueue was supposed to make sure the Deferred there is always executing every new handler attached to it as soon as it could. The idea being that you can call save several times on the record in short succession, but the calls will run one after another, and not overlap.

我使用的是推迟到排队Ajax调用,这样一个不运行,直到previous一次通话结束。然而,同样的方法,我想回到的jQuery的Ajax对象拒绝了递延能解决的/,像这样:

I am using a Deferred to enqueue Ajax calls, so that one does not run until the previous one call finished. However, from the same method, I want to return a Deferred that can be resolved/rejected by the jQuery Ajax object, like so:

 record.saveQueue = $.Deferred();

 self.save = function( record ){
    var deferredAction = $.Deferred();

    deferredAction.then(function() {
        return $.post("/example_save_endpoint");
    });

    record.saveQueue.always(function(){
      deferredAction.resolve();
    }).resolve();

    return deferredAction;
  }

然而,当我用这个code时, deferredAction 承诺最终总是解决,presumably因为#then处理程序返回一个等待(因此无排斥)的承诺。有没有什么办法来强制推迟到等到阿贾克斯承诺是解决前完成/拒绝?还是有其他更好的方式来穿针?

However, when I use this code, the deferredAction promise always ends up resolved, presumably because the #then handler is returning a "pending" (and thus non-rejecting) promise. Is there any way to force the Deferred to wait until the Ajax promise is complete before resolving/rejecting? Or is there another, better way to thread this needle?

推荐答案

我可能会选择不去做这种方式,但延迟/诺言的确可以作为一个排队的设备。

I would probably choose not to do it this way, but a deferred/promise can indeed be used as a queuing device.

您需要什么,你已经尝试过轻微的(?)的变化。

You need a slight(?) variation of what you already tried.

self.queue = $.when();//A resolved promise, used to form a queue of functions in a .then() chain.

self.save = function(data) {
    var dfrd = $.Deferred();//A Deferred dedicated to this particular save.
    self.queue = self.queue.then(function() {
        return $.post("/example_save_endpoint", data) //Make the AJAX call, and return a jqXHR to ensure the downstream queue waits for this jqXHR to resolve/reject.
            .then(dfrd.resolve, dfrd.reject) //Resolve/reject the Deferred for the caller's benefit
            .then(null, function() {
                //Force failure down the success path to ensure the queue is not killed by an AJAX failure.
                return $.when();//Return a resolved promsie, for the queue's benefit.
            });
    });
    return dfrd.promise();//allow the caller to do something when the AJAX eventually responds
}

有关说明,请参阅code评论的