This is an alternative to cancellable promises that relies entirely on existing JavaScript.

I'm posting this here in hopes to bring the discussion back to practical use cases and minimal needs.

Example:

Here's a setTimeout wrapper with cancellation, using a regular promise as a cancellation token.

let wait = (ms, cancel) => {
  let id;
  return Promise.race([
    new Promise(resolve => id = setTimeout(resolve, ms)),
    (cancel || new Promise(() => {})).then(() => clearTimeout(id))
  ]);
};

function CancelledError() {
  return Object.assign(new Error("The operation was cancelled."), {name: 
"CancelledError"});
}

// Demo:

async function foo() {
  try {
    let token = new Promise((r, e) => cancel.onclick = () => e(new 
CancelledError()));
    await wait(500);
    console.log("Wait 4 seconds...");
    await wait(4000, token);
    console.log("Then wait 3 more seconds...");
    await wait(3000, token);
    console.log("Done.");
  } catch (e) {
    if (e.name != "CancelledError") throw e;
    console.log("User cancelled");
  }
}
foo();


Here's the es6 version to run: http://jsfiddle.net/jib1/jz33qs32/

Things to note:
- Cancellation is targeted to specific operations (no "cancel chain" ambition).
- Token can be reused down the chain.
- Cancellation is propagated using a regular (new) CancellationError (no third rail).
- It is up to the caller whether to treat cancellations as non-exceptional.
- Basic Promise.race pattern works even to wrap APIs that aren't cancellable (stop waiting) - Pattern allows substituting any error (though I hope we standardize CancelledError). - Pattern allows chain resumption by resolving token with any desired value instead.

I don't think this group needs to develop much here, maybe standardize CancelledError, and have fetch() take a cancel promise argument like wait() does in the example above.

I'm open to hearing what use-cases are not be covered by this.

Looking forward to your feedback. Thanks!

.: Jan-Ivar :.

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to