Design Cancellable Function - Problem

Sometimes you have a long running task, and you may wish to cancel it before it completes. To help with this goal, write a function cancellable that accepts a generator object and returns an array of two values: a cancel function and a promise.

You may assume the generator function will only yield promises. It is your function's responsibility to pass the values resolved by the promise back to the generator. If the promise rejects, your function should throw that error back to the generator.

If the cancel callback is called before the generator is done, your function should throw an error back to the generator. That error should be the string "Cancelled" (Not an Error object). If the error was caught, the returned promise should resolve with the next value that was yielded or returned. Otherwise, the promise should reject with the thrown error. No more code should be executed.

When the generator is done, the promise your function returned should resolve the value the generator returned. If, however, the generator throws an error, the returned promise should reject with the error.

Input & Output

Example 1 — Cancellation Before Completion
$ Input: function* tasks() { const val = yield new Promise(resolve => resolve(2 + 2)); yield new Promise(resolve => setTimeout(resolve, 100)); return val + 1; }
Output: Promise rejects with "Cancelled"
💡 Note: Cancel is called at 50ms, before the 100ms timeout completes. The generator receives 'Cancelled' error and the promise rejects.
Example 2 — Normal Completion
$ Input: function* tasks() { const val = yield new Promise(resolve => resolve(3)); return val * 2; }
Output: Promise resolves with 6
💡 Note: No cancellation occurs, generator completes normally: 3 * 2 = 6
Example 3 — Caught Cancellation
$ Input: function* tasks() { try { yield new Promise(resolve => setTimeout(resolve, 100)); } catch { return 'caught'; } }
Output: Promise resolves with 'caught'
💡 Note: Cancellation error is caught by try-catch block, returns 'caught' instead of rejecting

Constraints

  • The generator function will only yield promises
  • Cancellation error must be the string "Cancelled"
  • Function must handle both caught and uncaught cancellation errors
  • Promise resolution must match generator completion state

Visualization

Tap to expand
Design Cancellable Function: Generator Control FlowGenerator Inputfunction* tasks() {yield Promise...Cancellable FunctionControls generatorvia .next() & .throw()Output Array[cancel function,promise]Cancellation Mechanics• Cancel function sets flag and triggers generator.throw("Cancelled")• Generator can catch cancellation and return value or let it propagate• Promise resolves/rejects based on generator completion stateCooperative cancellation with full generator lifecycle control
Understanding the Visualization
1
Input
Generator function that yields promises
2
Process
Create cancel function and promise, handle generator lifecycle
3
Output
Array with [cancel function, promise]
Key Takeaway
🎯 Key Insight: Use generator.throw() to inject cancellation errors, enabling cooperative cancellation patterns
Asked in
Google 25 Facebook 20 Amazon 15 Netflix 12
12.0K Views
Medium Frequency
~35 min Avg. Time
450 Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen