{"id":19320317,"url":"https://github.com/jstejada/interruptible","last_synced_at":"2025-04-22T18:30:32.231Z","repository":{"id":57275357,"uuid":"78403194","full_name":"jstejada/interruptible","owner":"jstejada","description":"interruptible functions in javascript","archived":false,"fork":false,"pushed_at":"2017-07-02T21:47:08.000Z","size":62,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-30T04:55:59.099Z","etag":null,"topics":["async-generator","coroutines","generators","interruptible-functions","javascript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jstejada.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-09T07:09:30.000Z","updated_at":"2024-06-07T07:59:59.000Z","dependencies_parsed_at":"2022-09-16T09:52:41.024Z","dependency_job_id":null,"html_url":"https://github.com/jstejada/interruptible","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstejada%2Finterruptible","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstejada%2Finterruptible/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstejada%2Finterruptible/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstejada%2Finterruptible/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jstejada","download_url":"https://codeload.github.com/jstejada/interruptible/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223902718,"owners_count":17222416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async-generator","coroutines","generators","interruptible-functions","javascript"],"created_at":"2024-11-10T01:28:15.780Z","updated_at":"2024-11-10T01:28:16.531Z","avatar_url":"https://github.com/jstejada.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Interrruptible.js\n\n`interruptible` is a library that makes asynchronous functions interruptible\nby using [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*).\n\n\n## Usage\n\nTo mark an async function as interruptible, convert it to a generator, and use\n`yield` to indicate where your function can be interrupted.\n\nFrom:\n```javascript\nasync function work (a, b) {\n  const foo = await makeFoo(a, b)\n  const result = await processFoo(foo)\n  return result\n}\n\nconst result = await work()\n```\n\nTo:\n```javascript\nimport {asInterruptible, InterruptError} from 'interruptible'\n\n\nasync function *interruptibleWork (a, b) {\n  const foo = yield makeFoo(a, b)  // Use `yield` to indicate that function can be interrupted after this async operation has resolved\n\n  // 🚫  If operation is interrupted before this line is reached, execution will stop here.\n\n  const result = await processFoo(foo)  // `await` wont stop execution even if operation is interrupted\n  return result\n}\n\nconst interruptibleTask = asInterruptible(interruptibleWork)\ntry {\n  const result = await interruptibleTask.run(this, 'a', 'b')\n} catch(error) {\n  if (error instanceof InterruptError) {\n    console.log('Interruptible task interrupted')\n    return\n  }\n  console.log('Interruptible task errored')\n}\n\n\n// You can interrupt the task from another execution context\nsetTimeout(() =\u003e {\n  if (someConiditon) {\n    interruptibleTask.interrupt()\n  }\n}, 100)\n```\n\n\n## Advanced Usage\n\n### Nested Generators\n\nYou can nest generators within generators, and interrupt them as well. The\ninterrupt will buble all the way to the parent generator:\n\n```javascript\n\nfunction *makeFoo(a, b) {\n  // Execution can also be stopped inside this generator\n  const resA = yield makeA(a)\n  const resB = yield makeB(b)\n  return resA + resB\n}\n\n\nasync function *interruptibleWork (a, b) {\n  const foo = yield makeFoo(a, b)\n\n  const result = await processFoo(foo)  // `await` wont stop execution even if operation is interrupted\n  return result\n}\n```\n\n### Async Generators\n\nYou may have noticed that in our example we used both `await` and `yield`\nkeywords:\n\n```javascript\n\nasync function *interruptibleWork (a, b) {\n  const foo = yield makeFoo(a, b)\n              -----\n\n  const result = await processFoo(foo)  // `await` wont stop execution even if operation is interrupted\n                 -----\n  return result\n}\n```\n\nThese are async generators, and are an ECMAScript Stage 3 [proposal](https://github.com/tc39/proposal-async-iteration#async-generator-functions).\nIn order to write these functions, you'll need to transpile your code with the\nappropriate babel [plugin](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-async-generator-functions).\n\n\n## Motivation\n\nYou may want to interrupt code for different reasons, principally in order to\nprevent work that is no longer needed.\n\nThe motivation for writing `interruptible` comes from the need of having a simple\nabstraction to be able write complex asynchronous tasks that could be\ninterrupted at different points of their execution by a scheduling system.\n\nIt is trivial to interrupt a single function using a conditional based on some\nstate, but it becomes extremely cumbersome to do so systematically across large\namounts of code when you want to be able to interrupt at different execution\npoints, and it ends up littering the code with `if` statements.\n\n`interruptible` provides a simple mechanism to do so, albeit with the cost\nof additional mental overhead of keeping in mind what using `yield` implies.\n\n\n## API\n\nSee libdef.js\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjstejada%2Finterruptible","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjstejada%2Finterruptible","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjstejada%2Finterruptible/lists"}