tgvashworth / fetch-engine

A smart request-making library
24 stars 6 forks source link

Cancelling all, but the most recent in-flight requests. #4

Closed waltfy closed 9 years ago

waltfy commented 9 years ago

What would a plugin that cancels all but the most recent request look like? Imagining the following scenario:

A text input used for search, which sends a HTTP request which is debounced at a 200ms rate.

Then imagine the following sample flow:

  1. User inputs 'donald', pauses for over 200ms.
    • Request A is sent for this search term. Request A is now in-flight.
  2. User continues to input 'donald duck', she is now done with her search term input.
    • Request B, is then sent. Request B is now in-flight.
  3. Request B, arrives and its results are used to render a list.
  4. Request A, arrives and its results are used to update the same list.
  5. User sees results for 'donald', rather than 'donald duck'.

There are various ways of solving this problem, most involve performing some reconciliation within the response handler — to decide whether the results list should be updated.

I am wondering what a plugin that cancels all but the most recent request, would look like?

Loving the work so far, think it adds a lot of value to complex data fetching.

tgvashworth commented 9 years ago

I think the best approach here would be to cancel the in-flight request A before B is sent. You could do this with a stateful plugin:

class PathPrefixFilter { ... }

class OneRequestInFlightPlugin {
  willFetch() {
    if (this.cancelCurrent) {
      this.cancelCurrent();
      delete this.cancelCurrent;
    }
  }
  fetch({ cancel }) {
    this.cancelCurrent = cancel;
  }
}

var fetch = new FetchEngine({
  plugins: [
    new FetchPreset({
      filters: [ new PathPrefixFilter('/search') ],
      plugins: [ new OneRequestInFlightPlugin() ]
    })
  ]
});

This is slightly fiddly becuase the response handling code will have to handle cancellations... but then it probably should be handling failures already.

tgvashworth commented 9 years ago

Closing, will come back to this use-case when there's an implementation.

waltfy commented 9 years ago

@phuu Makes sense. Thanks!