Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Last active September 4, 2015 11:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WebReflection/796d1f04b1173fbcfe5a to your computer and use it in GitHub Desktop.
Save WebReflection/796d1f04b1173fbcfe5a to your computer and use it in GitHub Desktop.
Optionally resolvable, rejectable, and cancelable Promises through abort.
function Lie(callback) {'use strict';
// (C) Andrea Giammarchi - MIT Style License
// this is now an official npm module https://github.com/WebReflection/dodgy#dodgy-
var
resolve, reject, abort,
lie = new Promise(function (res, rej) {
callback(res, rej, function onAbort(callback) {
resolve = res;
reject = rej; // feel free to use or ignore arguments
abort = function abort() { reject(callback.apply(null, arguments)); };
});
})
;
if (abort) { // optional opt in. We need to know how to abort
lie.resolve = resolve; // if we'd like to also expose how to resolve
lie.reject = reject; // or how to reject, so that we'll have full control.
lie.abort = abort; // if aborting doesn't require any specific action
} // a no-op Object as callback, as example, would do
// opt in for abort propagation
return (Lie.more || Object)(lie);
}
@WebReflection
Copy link
Author

Update

This is now an official module called dodgy


Example, how to opt in:

var p = new Lie(function (resolve, reject, onAbort) {
  var timeout = setTimeout(resolve, 1000, 'OK');
  onAbort(function () {
    clearTimeout(timeout);
    return 'aborted'; // will be used as rejected error
                      // it could even be undefined
                      // so it's easier to distinguish
                      // between real errors and aborts
  });
});

Optionally we could p.abort();, or p.resolve(123); or p.reject(new Error); and inspect it as such:

p.then(
  console.log.bind(console),
  console.warn.bind(console)
).catch(
  console.error.bind(console)
);

If we don't need to do anything particular on .abort() beside rejecting, we can opt in via

var p = new Lie(function (resolve, reject, onAbort) {
  onAbort(Object);
  // rest of the logic
});

If we just need a regular Promise, do not invoke onAbort or just ignore it.

var regPromise = new  Lie(function (res, rej) { /* not abort-able */ });

For all possible rants, complains, insults about this proposal, please use the rest of the internet, thank you.

@WebReflection
Copy link
Author

Update

This is now an official module called dodgy


Lie.more

In case we want to make abortability available down the chain:

Lie.more = function more(lie) {
  function wrap(previous) {
    return function () {
      var l = previous.apply(lie, arguments);
      l.resolve = lie.resolve;  // comment out if not  needed
      l.reject = lie.reject;    // comment out if not  needed
      l.abort = lie.abort;
      return Lie.more(l);
    };
  }
  if (lie.abort) {
    lie.then = wrap(lie.then);
    lie.catch = wrap(lie.catch);
  }
  return lie;
};

It is now possible to chain "All The Things" and live happily ever after.

var lie = new Lie(function (res, rej, onAbort) {
  var t = setTimeout(res, 1000, 'OK');
  onAbort(function (why) {
    clearTimeout(t);
    return why;
  });
})
.then(
  console.log.bind(console),
  console.warn.bind(console)
)
.catch(
  console.error.bind(console)
);

lie.abort('because');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment