javascript - Promise - is it possible to force cancel a promise -
i use es6 promises manage of network data retrieval , there situations need force cancel them.
basically scenario such have type-ahead search on ui request delegated backend has carry out search based on partial input. while network request (#1) may take little bit of time, user continues type triggers backend call (#2)
here #2 naturally takes precedence on #1 cancel promise wrapping request #1. have cache of promises in data layer can theoretically retrieve attempting submit promise #2.
but how cancel promise #1 once retrieve cache?
could suggest approach?
no. can't yet.
es6 promises not support cancellation yet. it's on way, , design lot of people worked hard on. sound cancellation semantics hard right , work in progress. there interesting debates on "fetch" repo, on esdiscuss , on several other repos on gh i'd patient if you.
but, but, but.. cancellation important!
it is, reality of matter cancellation really important scenario in client-side programming. cases describe aborting web requests important , they're everywhere.
so... language screwed me!
yeah, sorry that. promises had in first before further things specified - went in without useful stuff .finally
, .cancel
- it's on way though, spec through dom. cancellation not afterthought it's time constraint , more iterative approach api design.
so can do?
you have several alternatives:
- use third party library bluebird can move lot faster spec , have cancellation bunch of other goodies - large companies whatsapp do.
- pass cancellation token.
using third party library pretty obvious. token, can make method take function in , call it, such:
function getwithcancel(url, token) { // token cancellation var xhr = new xmlhttprequest; xhr.open("get", url); return new promise(function(resolve, reject) { xhr.onload = function() { resolve(xhr.responsetext); }); token.cancel = function() { // specify cancellation xhr.abort(); // abort request reject(new error("cancelled")); // reject promise }; xhr.onerror = reject; }); };
which let do:
var token = {}; var promise = getwithcancel("/someurl", token); // later want abort promise: token.cancel();
your actual use case - last
this isn't hard token approach:
function last(fn) { var lasttoken = { cancel: function(){} }; // start no op return function() { lasttoken.cancel(); var args = array.prototype.slice.call(arguments); args.push(lasttoken); return fn.apply(this, args); }; }
which let do:
var synced = last(getwithcancel); synced("/url1?q=a"); // canceled synced("/url1?q=ab"); // canceled synced("/url1?q=abc"); // canceled synced("/url1?q=abcd").then(function() { // run });
and no, libraries bacon , rx don't "shine" here because they're observable libraries, have same advantage user level promise libraries have not being spec bound. guess we'll wait have , see in es2016 when observables go native. are nifty typeahead though.
Comments
Post a Comment