[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"article-promise-with-resolvers":32,"code:js:true:fevjyc":247,"code:js:true:1iq232h":248,"code:js:true:hd3qbe":249,"code:js:true:1a23dzs":250,"code:js:true:1eclk2c":251,"code:js:true:qmj1mk":252,"code:ts:true:19ujv9s":253},[4,20],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Build. Learn. Ship.","Practical courses, engineering-grade articles and open-source tools for people who ship.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Structured paths, listening drills and spaced repetition that actually sticks.","amber-400","⌘",[13,15,29],"es",{"courses":17,"paths":17,"articles":18,"exams":18,"flashcards":18,"packages":18,"community":17,"certificates":18,"teams":18,"commerce":17},2,{"id":33,"slug":34,"title":35,"subtitle":36,"excerpt":37,"coverUrl":38,"locale":13,"readingMinutes":39,"publishedAt":40,"viewCount":41,"likeCount":19,"commentCount":19,"author":42,"vertical":47,"topic":48,"tags":51,"_count":63,"playground":65,"body":67,"bodyMd":229,"seo":230,"translationGroupId":234,"thread":235,"assessments":237,"translations":243,"quiz":245},"019fe660-66d6-71c3-b71a-ed9102b874c8","promise-with-resolvers","You keep escaping the Promise constructor. `Promise.withResolvers` does it right.",null,"The 'deferred promise' pattern — storing resolve and reject outside the constructor so you can call them later — is a daily JavaScript idiom that's always felt awkward. ES2024 added a one-liner for it.","\u002Fmedia\u002Fcovers\u002Fpromise-with-resolvers.png",4,"2026-07-22T08:35:52.029Z",29,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},"javascript","JavaScript",[52,54,57,60],{"slug":49,"name":53,"color":36},"Javascript",{"slug":55,"name":56,"color":36},"webdev","Webdev",{"slug":58,"name":59,"color":36},"typescript","Typescript",{"slug":61,"name":62,"color":36},"asyncjs","Asyncjs",{"assessments":64},1,{"slug":34,"title":66},"Promise.withResolvers() — interactive playground",{"blocks":68,"version":64},[69,73,79,82,85,90,93,97,100,103,106,109,112,115,118,121,124,128,131,135,138,141,144,148,151,154,157,161,164,167,170,173,176,179,184,187,190,193,196,199,202,205,208,211,214,217,220],{"id":70,"html":71,"type":72},"b1","\u003Cp>Every JavaScript developer has written this at least once:\u003C\u002Fp>","paragraph",{"id":74,"code":75,"type":76,"language":77,"highlight":78},"b2","let resolve, reject;\nconst promise = new Promise((res, rej) => {\n  resolve = res;\n  reject = rej;\n});\n\n\u002F\u002F Later…\neventBus.on('done', () => resolve(result));","code","js",[],{"id":80,"html":81,"type":72},"b3","\u003Cp>You need to trigger the Promise from outside the constructor — from an event listener, a callback, or a message handler. So you capture \u003Ccode>resolve\u003C\u002Fcode> and \u003Ccode>reject\u003C\u002Fcode> by leaking them into the outer scope. It works. It also looks wrong every time you write it, because you&#39;re manually escaping a closure that wasn&#39;t designed to be escaped.\u003C\u002Fp>",{"id":83,"html":84,"type":72},"b4","\u003Cp>ES2024 added the right tool for this: \u003Ccode>Promise.withResolvers\u003C\u002Fcode>.\u003C\u002Fp>",{"id":86,"html":87,"text":88,"type":89,"level":31},"b5","What \u003Ccode>Promise.withResolvers\u003C\u002Fcode> returns","What Promise.withResolvers returns","heading",{"id":91,"html":92,"type":72},"b6","\u003Cp>Instead of constructing a Promise and escaping its callbacks, you call a static method that hands you all three pieces at once:\u003C\u002Fp>",{"id":94,"code":95,"type":76,"language":77,"highlight":96},"b7","const { promise, resolve, reject } = Promise.withResolvers();",[],{"id":98,"html":99,"type":72},"b8","\u003Cp>\u003Ccode>promise\u003C\u002Fcode> is a regular Promise. \u003Ccode>resolve\u003C\u002Fcode> and \u003Ccode>reject\u003C\u002Fcode> are its resolution functions, already sitting in your scope. No closure escape needed. The pattern that used to take four lines now takes one.\u003C\u002Fp>",{"id":101,"html":102,"type":72},"b9","\u003Cp>The old pattern and the new one behave identically — the same microtask timing, the same error propagation, the same \u003Ccode>.then\u003C\u002Fcode>\u002F\u003Ccode>.catch\u003C\u002Fcode> interface. The difference is that the intent is now explicit: you&#39;re creating a deferred Promise on purpose, not as a workaround.\u003C\u002Fp>",{"id":104,"html":105,"type":72},"b10","\u003C!-- playground:start -->",{"id":107,"html":108,"text":108,"type":89,"level":31},"b11","🎮 Try it yourself",{"id":110,"html":111,"type":72},"b12","\u003Cp>\u003Cstrong>\u003Ca href=\"https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fposts\u002F2026-07-22-promise-with-resolvers\u002Fplayground\u002F\">▶️ Open the interactive playground →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":113,"html":114,"type":72},"b13","\u003Cp>\u003Cem>Runs right in your browser — poke at it and watch the concept react live.\u003C\u002Fem>\u003C\u002Fp>",{"id":116,"html":117,"type":72},"b14","\u003C!-- playground:end -->",{"id":119,"html":120,"text":120,"type":89,"level":31},"b15","The event-to-Promise bridge",{"id":122,"html":123,"type":72},"b16","\u003Cp>The clearest use case is wrapping event-based APIs in a Promise interface. Before:\u003C\u002Fp>",{"id":125,"code":126,"type":76,"language":77,"highlight":127},"b17","function waitForOpen(socket) {\n  let resolve, reject;\n  const promise = new Promise((res, rej) => {\n    resolve = res;\n    reject = rej;\n  });\n  socket.addEventListener('open', () => resolve());\n  socket.addEventListener('error', (e) => reject(e));\n  return promise;\n}",[],{"id":129,"html":130,"type":72},"b18","\u003Cp>After:\u003C\u002Fp>",{"id":132,"code":133,"type":76,"language":77,"highlight":134},"b19","function waitForOpen(socket) {\n  const { promise, resolve, reject } = Promise.withResolvers();\n  socket.addEventListener('open', () => resolve());\n  socket.addEventListener('error', (e) => reject(e));\n  return promise;\n}",[],{"id":136,"html":137,"type":72},"b20","\u003Cp>Same logic, much less ceremony. The function returns a Promise that resolves or rejects based on the socket&#39;s events — which is exactly what you&#39;d read from the clean version. The old version made you parse around the escape boilerplate to get there.\u003C\u002Fp>",{"id":139,"html":140,"text":140,"type":89,"level":31},"b21","Async queues and message passing",{"id":142,"html":143,"type":72},"b22","\u003Cp>A place where deferred Promises appear repeatedly is async queues — structures where a consumer awaits the next item and a producer calls \u003Ccode>push\u003C\u002Fcode> later:\u003C\u002Fp>",{"id":145,"code":146,"type":76,"language":77,"highlight":147},"b23","function createQueue() {\n  const pending = [];\n  let deferred = Promise.withResolvers();\n\n  return {\n    push(item) {\n      pending.push(item);\n      deferred.resolve();\n      deferred = Promise.withResolvers();\n    },\n\n    async *[Symbol.asyncIterator]() {\n      while (true) {\n        await deferred.promise;\n        while (pending.length) {\n          yield pending.shift();\n        }\n      }\n    },\n  };\n}\n\nconst queue = createQueue();\n\n\u002F\u002F Consumer\n(async () => {\n  for await (const item of queue) {\n    console.log('received:', item);\n  }\n})();\n\n\u002F\u002F Producer (elsewhere)\nqueue.push('hello');\nqueue.push('world');",[],{"id":149,"html":150,"type":72},"b24","\u003Cp>Each call to \u003Ccode>Promise.withResolvers()\u003C\u002Fcode> creates a fresh gate. The consumer waits on it; the producer resolves it when there&#39;s something to read. Without \u003Ccode>withResolvers\u003C\u002Fcode>, every one of those gates would need the escape boilerplate. With it, the queue logic reads straight through.\u003C\u002Fp>",{"id":152,"html":153,"text":153,"type":89,"level":31},"b25","Controlled flushing: waiting for a batch",{"id":155,"html":156,"type":72},"b26","\u003Cp>Another pattern: collecting items for a batch operation and resolving all waiters at once when the batch fires.\u003C\u002Fp>",{"id":158,"code":159,"type":76,"language":77,"highlight":160},"b27","class Batcher {\n  #items = [];\n  #deferred = Promise.withResolvers();\n\n  add(item) {\n    this.#items.push(item);\n    return this.#deferred.promise;\n  }\n\n  async flush() {\n    const batch = this.#items.splice(0);\n    const { resolve } = this.#deferred;\n    this.#deferred = Promise.withResolvers();\n    const results = await this.#processBatch(batch);\n    resolve(results);\n    return results;\n  }\n}",[],{"id":162,"html":163,"type":72},"b28","\u003Cp>Callers \u003Ccode>await batcher.add(item)\u003C\u002Fcode> and get the result when the batch flushes — whether that&#39;s triggered by a timer, a size limit, or explicit user action. Each flush resets the gate cleanly with a single \u003Ccode>Promise.withResolvers()\u003C\u002Fcode> call.\u003C\u002Fp>",{"id":165,"html":166,"text":166,"type":89,"level":31},"b29","When not to reach for it",{"id":168,"html":169,"type":72},"b30","\u003Cp>Deferred Promises are a tool for specific situations, not a general replacement for the constructor form. If you control both the setup and the resolution — \u003Ccode>fetch\u003C\u002Fcode>, \u003Ccode>fs.readFile\u003C\u002Fcode>, any async API you&#39;re directly awaiting — use \u003Ccode>async\u002Fawait\u003C\u002Fcode> or the Promise constructor directly. Deferred patterns are specifically for when setup and resolution happen in different execution contexts that can&#39;t share a callback cleanly.\u003C\u002Fp>",{"id":171,"html":172,"type":72},"b31","\u003Cp>One concrete anti-pattern: if you find yourself calling \u003Ccode>resolve\u003C\u002Fcode> synchronously inside the same function that created the deferred, you probably just wanted \u003Ccode>new Promise(res =&gt; res(value))\u003C\u002Fcode> — which is \u003Ccode>Promise.resolve(value)\u003C\u002Fcode>.\u003C\u002Fp>",{"id":174,"html":175,"text":175,"type":89,"level":31},"b32","TypeScript support",{"id":177,"html":178,"type":72},"b33","\u003Cp>TypeScript added \u003Ccode>Promise.withResolvers\u003C\u002Fcode> in version 5.4. The return type is typed correctly — \u003Ccode>PromiseWithResolvers&lt;T&gt;\u003C\u002Fcode> carries the type through:\u003C\u002Fp>",{"id":180,"code":181,"type":76,"language":182,"highlight":183},"b34","const { promise, resolve, reject } = Promise.withResolvers\u003Cstring>();\n\nresolve('hello');       \u002F\u002F ✅ string\nresolve(42);            \u002F\u002F ❌ type error","ts",[],{"id":185,"html":186,"type":72},"b35","\u003Cp>If you&#39;re on an older TS target, add \u003Ccode>&quot;ES2024&quot;\u003C\u002Fcode> to \u003Ccode>lib\u003C\u002Fcode> in your \u003Ccode>tsconfig.json\u003C\u002Fcode>.\u003C\u002Fp>",{"id":188,"html":189,"text":189,"type":89,"level":31},"b36","Browser support",{"id":191,"html":192,"type":72},"b37","\u003Cp>\u003Ccode>Promise.withResolvers\u003C\u002Fcode> is \u003Cstrong>Baseline 2024\u003C\u002Fstrong>: Chrome 119, Firefox 121, Safari 17.4, Node.js 22. If you&#39;re targeting modern environments, it&#39;s available with no polyfill. For older targets, the old escape pattern remains correct — \u003Ccode>withResolvers\u003C\u002Fcode> is syntax sugar for something you can always write by hand.\u003C\u002Fp>",{"id":194,"html":195,"type":72},"b38","\u003C!-- quiz:start -->",{"id":197,"html":198,"text":198,"type":89,"level":31},"b39","🧠 Test yourself",{"id":200,"html":201,"type":72},"b40","\u003Cp>Think it clicked? \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fquiz\u002Ftake.html?post=2026-07-22-promise-with-resolvers\">Take the 6-question quiz →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":203,"html":204,"type":72},"b41","\u003Cp>\u003Cem>Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.\u003C\u002Fem>\u003C\u002Fp>",{"id":206,"html":207,"type":72},"b42","\u003C!-- quiz:end -->",{"id":209,"html":210,"text":210,"type":89,"level":31},"b43","The takeaway",{"id":212,"html":213,"type":72},"b44","\u003Cp>Search your codebase for the pattern \u003Ccode>let resolve\u003C\u002Fcode> or \u003Ccode>let reject\u003C\u002Fcode> followed by a \u003Ccode>new Promise\u003C\u002Fcode>. Every one of those is a deferred Promise written the hard way. \u003Ccode>Promise.withResolvers()\u003C\u002Fcode> names the pattern, eliminates the escape boilerplate, and makes the intent readable at a glance. The result is the same; the code is cleaner by a visible margin.\u003C\u002Fp>",{"id":215,"type":216},"b45","divider",{"id":218,"html":219,"type":72},"b46","\u003Cp>\u003Cem>Thanks for reading! Let&#39;s stay connected:\u003C\u002Fem>\u003C\u002Fp>",{"id":221,"type":222,"items":223,"ordered":18},"b47","list",[224,225,226,227,228],"⭐ \u003Cstrong>GitHub\u003C\u002Fstrong> — follow me and star the projects: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fparsajiravand\">github.com\u002Fparsajiravand\u003C\u002Fa>","💬 \u003Cstrong>Discord\u003C\u002Fstrong> — join the frontend best-practices community: \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ\">discord.gg\u002Fd9KRhuAwQ\u003C\u002Fa>","📸 \u003Cstrong>Instagram\u003C\u002Fstrong> — frontend best practices, daily: \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F\">@bestpractice___\u003C\u002Fa>","💼 \u003Cstrong>LinkedIn\u003C\u002Fstrong> — \u003Ca href=\"https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F\">linkedin.com\u002Fin\u002Fparsa-jiravand\u003C\u002Fa>","✉️ \u003Cstrong>Email\u003C\u002Fstrong> (work &amp; contract inquiries): \u003Ca href=\"mailto:bestpractice2026@gmail.com\">bestpractice2026@gmail.com\u003C\u002Fa>","Every JavaScript developer has written this at least once:\n\n```js\nlet resolve, reject;\nconst promise = new Promise((res, rej) => {\n  resolve = res;\n  reject = rej;\n});\n\n\u002F\u002F Later…\neventBus.on('done', () => resolve(result));\n```\n\nYou need to trigger the Promise from outside the constructor — from an event listener, a callback, or a message handler. So you capture `resolve` and `reject` by leaking them into the outer scope. It works. It also looks wrong every time you write it, because you're manually escaping a closure that wasn't designed to be escaped.\n\nES2024 added the right tool for this: `Promise.withResolvers`.\n\n## What `Promise.withResolvers` returns\n\nInstead of constructing a Promise and escaping its callbacks, you call a static method that hands you all three pieces at once:\n\n```js\nconst { promise, resolve, reject } = Promise.withResolvers();\n```\n\n`promise` is a regular Promise. `resolve` and `reject` are its resolution functions, already sitting in your scope. No closure escape needed. The pattern that used to take four lines now takes one.\n\nThe old pattern and the new one behave identically — the same microtask timing, the same error propagation, the same `.then`\u002F`.catch` interface. The difference is that the intent is now explicit: you're creating a deferred Promise on purpose, not as a workaround.\n\n\u003C!-- playground:start -->\n\n## 🎮 Try it yourself\n\n**[▶️ Open the interactive playground →](https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fposts\u002F2026-07-22-promise-with-resolvers\u002Fplayground\u002F)**\n\n_Runs right in your browser — poke at it and watch the concept react live._\n\n\u003C!-- playground:end -->\n\n## The event-to-Promise bridge\n\nThe clearest use case is wrapping event-based APIs in a Promise interface. Before:\n\n```js\nfunction waitForOpen(socket) {\n  let resolve, reject;\n  const promise = new Promise((res, rej) => {\n    resolve = res;\n    reject = rej;\n  });\n  socket.addEventListener('open', () => resolve());\n  socket.addEventListener('error', (e) => reject(e));\n  return promise;\n}\n```\n\nAfter:\n\n```js\nfunction waitForOpen(socket) {\n  const { promise, resolve, reject } = Promise.withResolvers();\n  socket.addEventListener('open', () => resolve());\n  socket.addEventListener('error', (e) => reject(e));\n  return promise;\n}\n```\n\nSame logic, much less ceremony. The function returns a Promise that resolves or rejects based on the socket's events — which is exactly what you'd read from the clean version. The old version made you parse around the escape boilerplate to get there.\n\n## Async queues and message passing\n\nA place where deferred Promises appear repeatedly is async queues — structures where a consumer awaits the next item and a producer calls `push` later:\n\n```js\nfunction createQueue() {\n  const pending = [];\n  let deferred = Promise.withResolvers();\n\n  return {\n    push(item) {\n      pending.push(item);\n      deferred.resolve();\n      deferred = Promise.withResolvers();\n    },\n\n    async *[Symbol.asyncIterator]() {\n      while (true) {\n        await deferred.promise;\n        while (pending.length) {\n          yield pending.shift();\n        }\n      }\n    },\n  };\n}\n\nconst queue = createQueue();\n\n\u002F\u002F Consumer\n(async () => {\n  for await (const item of queue) {\n    console.log('received:', item);\n  }\n})();\n\n\u002F\u002F Producer (elsewhere)\nqueue.push('hello');\nqueue.push('world');\n```\n\nEach call to `Promise.withResolvers()` creates a fresh gate. The consumer waits on it; the producer resolves it when there's something to read. Without `withResolvers`, every one of those gates would need the escape boilerplate. With it, the queue logic reads straight through.\n\n## Controlled flushing: waiting for a batch\n\nAnother pattern: collecting items for a batch operation and resolving all waiters at once when the batch fires.\n\n```js\nclass Batcher {\n  #items = [];\n  #deferred = Promise.withResolvers();\n\n  add(item) {\n    this.#items.push(item);\n    return this.#deferred.promise;\n  }\n\n  async flush() {\n    const batch = this.#items.splice(0);\n    const { resolve } = this.#deferred;\n    this.#deferred = Promise.withResolvers();\n    const results = await this.#processBatch(batch);\n    resolve(results);\n    return results;\n  }\n}\n```\n\nCallers `await batcher.add(item)` and get the result when the batch flushes — whether that's triggered by a timer, a size limit, or explicit user action. Each flush resets the gate cleanly with a single `Promise.withResolvers()` call.\n\n## When not to reach for it\n\nDeferred Promises are a tool for specific situations, not a general replacement for the constructor form. If you control both the setup and the resolution — `fetch`, `fs.readFile`, any async API you're directly awaiting — use `async\u002Fawait` or the Promise constructor directly. Deferred patterns are specifically for when setup and resolution happen in different execution contexts that can't share a callback cleanly.\n\nOne concrete anti-pattern: if you find yourself calling `resolve` synchronously inside the same function that created the deferred, you probably just wanted `new Promise(res => res(value))` — which is `Promise.resolve(value)`.\n\n## TypeScript support\n\nTypeScript added `Promise.withResolvers` in version 5.4. The return type is typed correctly — `PromiseWithResolvers\u003CT>` carries the type through:\n\n```ts\nconst { promise, resolve, reject } = Promise.withResolvers\u003Cstring>();\n\nresolve('hello');       \u002F\u002F ✅ string\nresolve(42);            \u002F\u002F ❌ type error\n```\n\nIf you're on an older TS target, add `\"ES2024\"` to `lib` in your `tsconfig.json`.\n\n## Browser support\n\n`Promise.withResolvers` is **Baseline 2024**: Chrome 119, Firefox 121, Safari 17.4, Node.js 22. If you're targeting modern environments, it's available with no polyfill. For older targets, the old escape pattern remains correct — `withResolvers` is syntax sugar for something you can always write by hand.\n\n\u003C!-- quiz:start -->\n\n## 🧠 Test yourself\n\nThink it clicked? **[Take the 6-question quiz →](https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fquiz\u002Ftake.html?post=2026-07-22-promise-with-resolvers)**\n\n_Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._\n\n\u003C!-- quiz:end -->\n\n## The takeaway\n\nSearch your codebase for the pattern `let resolve` or `let reject` followed by a `new Promise`. Every one of those is a deferred Promise written the hard way. `Promise.withResolvers()` names the pattern, eliminates the escape boilerplate, and makes the intent readable at a glance. The result is the same; the code is cleaner by a visible margin.\n\n---\n\n*Thanks for reading! Let's stay connected:*\n\n- ⭐ **GitHub** — follow me and star the projects: [github.com\u002Fparsajiravand](https:\u002F\u002Fgithub.com\u002Fparsajiravand)\n- 💬 **Discord** — join the frontend best-practices community: [discord.gg\u002Fd9KRhuAwQ](https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ)\n- 📸 **Instagram** — frontend best practices, daily: [@bestpractice___](https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F)\n- 💼 **LinkedIn** — [linkedin.com\u002Fin\u002Fparsa-jiravand](https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F)\n- ✉️ **Email** (work & contract inquiries): [bestpractice2026@gmail.com](mailto:bestpractice2026@gmail.com)",{"title":231,"canonical":232,"description":233},"You keep escaping the Promise constructor. `Promise.withResolvers` doe","https:\u002F\u002Fbestpractic.org\u002Fblog\u002Fpromise-with-resolvers","The 'deferred promise' pattern — storing resolve and reject outside the constructor so you can call them later — is a daily JavaScript idiom that's always felt awkward. ES2024 adde","019fe660-66d6-71c3-b71a-f3b1c5717a33",{"id":236,"locked":18},"019fe660-6df1-72dc-9271-b3b33701aef2",[238],{"id":239,"slug":34,"title":240,"_count":241},"019fe776-6c4a-702d-9222-5164bd838f73","Promise.withResolvers()",{"questions":242},6,[244],{"locale":13,"slug":34},{"id":239,"slug":34,"title":240,"_count":246,"questionCount":242},{"questions":242},"\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">let\u003C\u002Fspan> resolve\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> reject;\n\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> promise \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>res\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> rej\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  resolve \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> res;\n  reject \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> rej;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F Later…\n\u003C\u002Fspan>eventBus\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">on\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'done'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-func\">resolve\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>result\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-oneline\" data-lang=\"js\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> promise\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> resolve\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> reject \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">withResolvers\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003Cdiv>10\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">function\u003C\u002Fspan> \u003Cspan class=\"shj-func\">waitForOpen\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>socket\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">let\u003C\u002Fspan> resolve\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> reject;\n  \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> promise \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>res\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> rej\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    resolve \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> res;\n    reject \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> rej;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  socket\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">addEventListener\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'open'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-func\">resolve\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  socket\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">addEventListener\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'error'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>e\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-func\">reject\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>e\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> promise;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">function\u003C\u002Fspan> \u003Cspan class=\"shj-func\">waitForOpen\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>socket\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> promise\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> resolve\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> reject \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">withResolvers\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  socket\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">addEventListener\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'open'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-func\">resolve\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  socket\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">addEventListener\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'error'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>e\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-func\">reject\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>e\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> promise;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003Cdiv>10\u003C\u002Fdiv>\u003Cdiv>11\u003C\u002Fdiv>\u003Cdiv>12\u003C\u002Fdiv>\u003Cdiv>13\u003C\u002Fdiv>\u003Cdiv>14\u003C\u002Fdiv>\u003Cdiv>15\u003C\u002Fdiv>\u003Cdiv>16\u003C\u002Fdiv>\u003Cdiv>17\u003C\u002Fdiv>\u003Cdiv>18\u003C\u002Fdiv>\u003Cdiv>19\u003C\u002Fdiv>\u003Cdiv>20\u003C\u002Fdiv>\u003Cdiv>21\u003C\u002Fdiv>\u003Cdiv>22\u003C\u002Fdiv>\u003Cdiv>23\u003C\u002Fdiv>\u003Cdiv>24\u003C\u002Fdiv>\u003Cdiv>25\u003C\u002Fdiv>\u003Cdiv>26\u003C\u002Fdiv>\u003Cdiv>27\u003C\u002Fdiv>\u003Cdiv>28\u003C\u002Fdiv>\u003Cdiv>29\u003C\u002Fdiv>\u003Cdiv>30\u003C\u002Fdiv>\u003Cdiv>31\u003C\u002Fdiv>\u003Cdiv>32\u003C\u002Fdiv>\u003Cdiv>33\u003C\u002Fdiv>\u003Cdiv>34\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">function\u003C\u002Fspan> \u003Cspan class=\"shj-func\">createQueue\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> pending \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-kwd\">let\u003C\u002Fspan> deferred \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">withResolvers\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\n  \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-func\">push\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>item\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n      pending\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">push\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>item\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n      deferred\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">resolve\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n      deferred \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">withResolvers\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\n    \u003Cspan class=\"shj-kwd\">async\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">*\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-class\">Symbol\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>asyncIterator\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n      \u003Cspan class=\"shj-kwd\">while\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bool\">true\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n        \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> deferred\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>promise;\n        \u003Cspan class=\"shj-kwd\">while\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>pending\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>length\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n          \u003Cspan class=\"shj-kwd\">yield\u003C\u002Fspan> pending\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">shift\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n        \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n      \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n    \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> queue \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-func\">createQueue\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F Consumer\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">async\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">=&gt;\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">for\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> item \u003Cspan class=\"shj-kwd\">of\u003C\u002Fspan> queue\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">log\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'received:'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> item\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F Producer (elsewhere)\n\u003C\u002Fspan>queue\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">push\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'hello'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\nqueue\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">push\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'world'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003Cdiv>10\u003C\u002Fdiv>\u003Cdiv>11\u003C\u002Fdiv>\u003Cdiv>12\u003C\u002Fdiv>\u003Cdiv>13\u003C\u002Fdiv>\u003Cdiv>14\u003C\u002Fdiv>\u003Cdiv>15\u003C\u002Fdiv>\u003Cdiv>16\u003C\u002Fdiv>\u003Cdiv>17\u003C\u002Fdiv>\u003Cdiv>18\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Batcher\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  #items \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">[\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">]\u003C\u002Fspan>;\n  #deferred \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">withResolvers\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\n  \u003Cspan class=\"shj-func\">add\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>item\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>#items\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">push\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>item\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>#deferred\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>promise;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\n  \u003Cspan class=\"shj-kwd\">async\u003C\u002Fspan> \u003Cspan class=\"shj-func\">flush\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> batch \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>#items\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">splice\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-num\">0\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> resolve \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>#deferred;\n    \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>#deferred \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">withResolvers\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> results \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>#\u003Cspan class=\"shj-func\">processBatch\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>batch\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-func\">resolve\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>results\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> results;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> promise\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> resolve\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> reject \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Promise\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>withResolvers\u003Cspan class=\"shj-oper\">&lt;\u003C\u002Fspan>string\u003Cspan class=\"shj-oper\">&gt;\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\n\u003Cspan class=\"shj-func\">resolve\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'hello'\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;       \u003Cspan class=\"shj-cmnt\">\u002F\u002F ✅ string\n\u003C\u002Fspan>\u003Cspan class=\"shj-func\">resolve\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-num\">42\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;            \u003Cspan class=\"shj-cmnt\">\u002F\u002F ❌ type error\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>"]