{"id":22202238,"url":"https://github.com/rumkin/tc39-synced-function","last_synced_at":"2025-07-17T06:04:32.520Z","repository":{"id":152260219,"uuid":"222130166","full_name":"rumkin/tc39-synced-function","owner":"rumkin","description":"TC39 Proposal for synchronized function","archived":false,"fork":false,"pushed_at":"2019-11-18T04:54:24.000Z","size":29,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T01:42:20.866Z","etag":null,"topics":["javascript","proposal","tc39"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rumkin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-16T16:49:13.000Z","updated_at":"2020-05-13T09:19:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"206f8c88-70ef-43ba-934e-0e8f2ad3eb2b","html_url":"https://github.com/rumkin/tc39-synced-function","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rumkin/tc39-synced-function","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Ftc39-synced-function","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Ftc39-synced-function/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Ftc39-synced-function/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Ftc39-synced-function/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rumkin","download_url":"https://codeload.github.com/rumkin/tc39-synced-function/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Ftc39-synced-function/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265571143,"owners_count":23790025,"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":["javascript","proposal","tc39"],"created_at":"2024-12-02T16:12:51.947Z","updated_at":"2025-07-17T06:04:32.503Z","avatar_url":"https://github.com/rumkin.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Synchronized function syntax\n\nThis proposal suggests creation of a new kind of syntax and semantic for asynchronous functions, socalled synchronized function. It's logic is opposite to async functions, it awaits promises automatically without using `await` keyword and use `nowait` to prevent call from resolution.\n\n## Rationale\n\nAsync functions were created to reduce nesting and simplify code. Currently async functions are using to make call behav like a synchronous function and it's a very rare/specific case when developers need to make async function not to wait a promise resolution in current call. Thus async functions are flooded by `await` statements.\n\nCurrent async/await syntax has bunch of issues:\n\n1. It couldn't solve chained promises and lead to weird expressions like this `await (await fetch(url)).json()`.\n2. It makes harder to implement other language features like pipeline operator which couldn't use asyncronous code `x |\u003e async (url) =\u003e fetch(url).then((res) =\u003e res.json()) |\u003e await`.\n3. It requires custom solutions for other language feauters like async for-loop.\n\nSynchronized function solves this issues and reduces syntax complexity. It resolves all promises returend by function call, even from chained calls. It's still asynchronous under the hood and returns a promise like regular async function do, so it isn't blocking too. In the case when developers still need to move a call to another event-frame, they can use `setImmediate/setTimeout` or `nowait` keyword.\n\n## Syntax\n\n### Regular function\n\nSynchromized functions requires `synced` keyword placed before the function. Also it uses `nowait` keyword to prevent a promise resolution.\n\nExample:\n\n```\nsynced function request(url) {\n  return fetch(url).json()\n}\n```\n\n### Arrow function\n\nIt seems logical to make this behavior the default due to its simplicity and to use `~\u003e` construction for synced function definition of arrow function (instead of a keyword).\n\nExample:\n```\nconst get = (url) ~\u003e fetch(url).json()\n```\n\n## Resolution\n\nSynced function resolves each function call or constructor call result. It doesn't resolve object properties.\n\nConstructor resolution:\n```\nsynced function example() {\n  const result = new Promise((resolve) =\u003e setImmediate(resolve, true)) // would be resolved\n  result // -\u003e true\n}\n```\n\nExternal promise resolution:\n```\nconst promise = new Promise((resolve) =\u003e setImmediate(resolve, true))\n\nsynced function example() {\n  const result = promise.then() // would be resolved\n  result // -\u003e true\n}\n```\n\n## Examples\n\n### Chained call\n\nRegular async function:\n```js\nasync function request(url) {\n  const res = await fetch(url)\n  const json = await res.json()\n  return json\n}\n```\n\nSynchronized function:\n```js\nsynced function request(url) {\n  return fetch(url).json()\n}\n```\n\n### Nowait and promises\n\nRegular async function:\n```js\nasync function request(url) {\n  const promise = fetch(url).then((res) =\u003e res.json())\n  const json = await promise\n}\n```\n\nSynchronized function:\n```js\nsynced function request(url) {\n  const promise = nowait fetch(url)\n  const json = promise.then().json()\n}\n```\n\n### Parallel resolution\n\nRegular async function:\n```js\nasync function request(urls) {\n  const responses = await Promise.all([\n    fetch(urls[0]),\n    fetch(urls[1]),\n  ])\n\n  return responses\n}\n```\n\nSynchronized function:\n```js\nsynced function request(urls) {\n  const responses = Promise.all([\n    nowait fetch(urls[0]),\n    nowait fetch(urls[1]),\n  ])\n  \n  return responses\n}\n```\n\nSynchronized function (without `nowait`):\n```js\nfunction parallel(fs) {\n  return Promise.all(fs.map(f =\u003e f()))\n}\n\nsynced function request(urls) {\n  const responses = parallel([\n    () =\u003e fetch(urls[0]),\n    () =\u003e fetch(urls[1]),\n  ])\n  \n  return responses\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumkin%2Ftc39-synced-function","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frumkin%2Ftc39-synced-function","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumkin%2Ftc39-synced-function/lists"}