ZucchiniZe
ZucchiniZe

Reputation: 301

Promise queues?

I have an application that is sending a http request that returns a promise everytime the user types. I have it debouncing every 500ms. Sometimes the api I am requesting takes a long time to respond. For example, I make a search request for a that takes a long time to respond but then the user continues typing to complete the query of a+x which resolves almost immediately but the results of a+x get overridden by the previous request of just a.

TL;DR: if new promise is called before current resolves, how to cancel current

Upvotes: 0

Views: 1245

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074088

The way I usually handle overlapping queries where I only want the results of the last one is to remember something that I can check in the callback.

You haven't quoted any code which makes it tricky to help, but here's an example:

"use strict";
// NOTE: Will only run if your browser supports promises.

// Scoping function to avoid globals
(function() {
  // We keep track of the most recent promise
  var lastSomethingRequest = null;
  
  // Our function that does something async
  function doSomething(value) {
    console.log("doing request for " + value);
    
    // Start the async, remember the promise
    var p = new Promise(function(resolve) {
      setTimeout(function() {
        resolve("resolve for " + value);
      }, Math.floor(Math.random() * 500));
    });
    
    // Remember that as the most recent one
    lastSomethingRequest = p;
    p.then(function(result) {
      // Use the result only if it's the most recent
      if (lastSomethingRequest === p) {
        console.log("Use this result: " + result);
        lastSomethingRequest = null; // Release the promise object
      } else {
        console.log("Disregard outdated result: " + result);
      }
    });
  }

  // Generate 5 requests in a row that will complete in varying
  // amounts of time, where we only want the result of the last one
  for (var n = 0; n < 5; ++n) {
    doSomething(n);
  }
})();

Upvotes: 1

user3707125
user3707125

Reputation: 3474

Create a variable that counts your requests:

var effectiveRequestNumber = 0;

function asyncRequest() {       
    var requestNumber = ++effectiveRequestNumber; // storing our request number
    doSomething().then(function(response) {
        // if the function was invoked after this request, then these two won't match
        if (effectiveRequestNumber !== requestNumber) {
            return;
        } 
        applyResponse(response); // we are fine - applying the response
    });
}

Upvotes: 2

Related Questions