GithubHelp home page GithubHelp logo

Comments (3)

catamphetamine avatar catamphetamine commented on May 28, 2024

I see, so you're suggesting to add an extra .abort() method for the Promise being returned.
That's a viable solution since Promise spec is unlikely to ever use such method name so it can be considered safe.
Still I implemented it the other way.

Your use case isn't clear.
I guess it's some kind of a background refresh task which is supposed to terminate when the user clicks the same "refresh" button once again.
I'm not sure though how're you gonna cancel the previous request in such a scenario.
Storing it in window? Not the most elegant solution.
But it has to be stored somewhere.
State is supposed to be JSON-only, as far as I understood Redux concept.
So, I guess, window would be the way to go (with no storing on the server side).
And where the cancellation would take place.
Maybe inside reducer, but reducers aren't supposed to take any actions at all as per Redux concept.
So, I guess, the cancellation would happen inside the action itself, like

if (window.______pending_request && the request is still running)
{
  window._______pending_request.abort()
}

As for the other possible ways of obtaining the way to call the .abort() method it could be done via options.

http.post('/', {}, { onRequest: request => window.request = request })

That would be more verbose though but it doesn't hack around the Promise object.

Another thing is retrying: if http request retrying is set up then it wouldn't make sense to call .abort() on the Promise which has already been superseded by a new one (therefore having no effect).
A better way would be using the already existing Promise chain cancellation concept.
http://bluebirdjs.com/docs/api/cancellation.html
I added http utility cancellation, I guess it's gonna work, but only for Bluebird users who enabled Promise cancellation.

Even if retrying isn't used I could add .abort() method for the Promise itself but it's not being returned from http methods: it's being .then()ned and therefore a whole another Promise is returned from the method.

So instead I added the onRequest(request) parameter to http utility method options.

The following works for me:

http.get('/api/example/users', {}, { onRequest: x => x.abort() })

See if it works for you

npm install react-isomorphic-render@latest

from react-pages.

katzoo avatar katzoo commented on May 28, 2024

Hey, thanks for a quick response!

Sorry, I should have stated this in my previous comment, but my main use case for this feature was autocomplete/search component that sends debounced requests to api every time user input changes. Cancelling 'dispatched' Promise works fine from the user perspective (eg. results from old query aren't saved in redux store), but there is no need to put unnecessary stress on backend (imagine slow connection with a few seconds delay).

A better way would be using the already existing Promise chain cancellation concept.
http://bluebirdjs.com/docs/api/cancellation.html
I added http utility cancellation, I guess it's gonna work, but only for Bluebird users who enabled Promise cancellation.

Thanks a lot for this, my project has Bluebird configured, so it's a great fit for the original use case, also it's probably the cleanest approach. I haven't tested your changes yet, but I'm confident they completely cover my issue.

Instead of storing them somewhere on global object, I'd rather go for a simple middleware similar to one below (haven't run/tested this, but assumes Bluebird cancellation is available):

const cancelPreviousMiddleware = store => {
  const toCancel = new Map();

  return next => action => {
    const result = next(action);

    if (check if on client && action.cancelPrevious) {
      const [type] = action.events;

      if (toCancel.get(type)) {
        toCancel.get(type).cancel();
      }

      if (result.promise && typeof result.promise.cancel === 'function') {
        toCancel.set(type, result.promise);

        result.promise.finally(() => { toCancel.delete(type); }
      }
    }

    return result;
  };
};

and then dispatching again action of the same type should do the trick:

function asyncAction() {
  return {
    promise: html => html.get(...),
    events: [....],
    cancelPrevious: true,
  }
}

Initially I thought that somehow exposing superagent's abort would be enough and allow people without Bluebird to cancel requests when needed, but now with both additions (onCancel and onRequest) this is still possible, by having the middleware extend action.promise options with onRequest that stores superagent request and abort's it when it's called again.

Thanks once again!

from react-pages.

catamphetamine avatar catamphetamine commented on May 28, 2024

Ah, now I see what you mean.
I guess that's a generic enough case to make it part of the library.
Even though I find the "2 seconds delay before it even hits the server" case extremely unlikely.
I removed onRequest option and added cancelPrevious: true flag to asynchronous actions.
(see the updated readme for details)
And also watch out for .finally because it's only for bluebird and would break the default Promise implementation.

from react-pages.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.