UNPKG

@fbltd/async

Version:

Miscellaneous async utils

45 lines (44 loc) 1.85 kB
import { Dependency } from "../../dependency.js"; import { symAI } from "../../../constants.js"; import { runFnWithDepCollection } from "./utils.js"; export function reaction(fn, config) { let { result, deps } = runFnWithDepCollection(fn); const dep = new Dependency(result, config); async function subscribe() { const stream = { [symAI]: () => { let depsArray; let beforeValues; let obj = { next: async () => { depsArray = Array.from(deps); beforeValues = depsArray.map(dep => dep.value_unsafe); const promises = depsArray.map(dep => dep.next()); promises.push(dep.disposePromise); await Promise.race(promises); if (dep.done) return { done: true }; let shouldRun = depsArray.some((dep, i) => dep.value_unsafe !== beforeValues[i]); if (shouldRun) { ({ result, deps } = runFnWithDepCollection(fn)); return { done: false, value: result }; } else { for (let dep of deps) { if (dep.done) deps.delete(dep); } if (!deps.size) return { done: true }; return obj.next(); } } }; return obj; } }; for await (let value of stream) { dep.value = value; } } subscribe().then(() => dep.dispose()); return dep; }