Force jQuery Deferred to wait until Ajax complete in “then” handler

后端 未结 2 855
情话喂你
情话喂你 2021-01-26 08:28

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

2条回答
  •  天涯浪人
    2021-01-26 09:05

    Your idea might work, but

    • the queue must not be resolved using .resolve() every time the method is called, instead it should be initialised only with a resolved promise.
    • to actually queue on the record.saveQueue, it needs to be changed (overwritten) on every method call, to represent the end of the latest request.

    And we don't need any deferreds for that, as we can work with the promises that $.post returns.

    So use this:

    var emptyQueue = $.when(undefined); // an already fulfilled promise as the start
    // equivalent: = $.Deferred().resolve().promise();
    
    function startQueue() {
        return emptyQueue; // yes, this delibaretely returns a constant, the begin
                           // of the queue always looks the same (and is never mutated)
    }
    
    // every time you create a record, do
    record.saveQueue = startQueue();
    
    // and use that in your methods:
    this.save = function(record) {
        var queuedRequestResult = record.saveQueue.then(function() {
            return $.post("/example_save_endpoint");
    //      ^^^^^^ promises chain :-)
        });
        // Magic happens here:
        record.saveQueue = queuedRequestResult // we swap the previous queue promise for a new
                                               // one that resolves only after the request
          .then(startQueue, startQueue);       // and make sure it then starts with a fresh
                                               // queue, especially when the request failed
        //.then(null, startQueue) is similar, except unnecessarily remembering the last result
        return queuedRequestResult;
    }
    

提交回复
热议问题