promise-latest
gives you a function that can be used to decorate a promise-returning function to make sure multiple calls to it always resolve with the value from the most recent promise returned by the original function.
If a promise returning function gets invoked and the promise returned by the previous call is still in progress, the previously returned promise(s) will instead be resolved with the value from the promise returned by the most recent call.
An example:
var latest = { return { }} var latestFromUnpredictable = var slow = var fastest = var faster = slow faster fastest // Will take around 10 ms and print operation took 100ms operation took 100ms operation took 100ms
A great use case is for preventing out of order results while the user types in an auto-complete:
user type 'c' -> search for 'c'
user type 'a' -> search for 'ca'
user type 't' -> search for 'cat'
Since 'c' is a much broader search term than 'cat', the operation search for 'c'
may take longer time to process, so maybe you'll get the results in this order:
10ms => result of search for 'cat'
50ms => result of search for 'ca'
100ms => result of search for 'c'
Now, if your code handling search looks like this, you are in trouble, because the result of search c
will be presented
to the user after the result from both cat
and ca
searchElement
This can be easily fixed by decorating the ajax function above with:
var latest = var latestAjax = // do not worry about out of order resultssearchElement
What you should know is that even though presentResult will be called after the latest request finishes, presentSearchResult
will still be called three times with the same arguments. Which is suboptimal. To avoid this you could use some kind of
throttling or argument diffing.
Also, if the user types really fast, there's arguably no need to actually perform three requests. Avoid this by debouncing the ajax function.
A note about cancellation / debouncing
latest-promise
does not provide any kind of throttling / debouncing. It will call function you provide whenever
the function returned from latest(...)
is called. If/when native promises comes with an ability to be cancelled,
any promise that is ongoing when the function receives a new call may be cancelled. In the mean time, you can use a
module that debounces promises to avoid unneccesary work.