CoolFace
Apppublic

sourav-das/stem-separator

sourceHugging Facemitupdated 6mo agoView on Hugging Face
3likes
README.md197 linesDownload Raw Back to gensync
1# gensync2 3This module allows for developers to write common code that can share4implementation details, hiding whether an underlying request happens5synchronously or asynchronously. This is in contrast with many current Node6APIs which explicitly implement the same API twice, once with calls to7synchronous functions, and once with asynchronous functions.8 9Take for example `fs.readFile` and `fs.readFileSync`, if you're writing an API10that loads a file and then performs a synchronous operation on the data, it11can be frustrating to maintain two parallel functions.12 13 14## Example15 16```js17const fs = require("fs");18const gensync = require("gensync");19 20const readFile = gensync({21  sync: fs.readFileSync,22  errback: fs.readFile,23});24 25const myOperation = gensync(function* (filename) {26  const code = yield* readFile(filename, "utf8");27 28  return "// some custom prefix\n" + code;29});30 31// Load and add the prefix synchronously:32const result = myOperation.sync("./some-file.js");33 34// Load and add the prefix asynchronously with promises:35myOperation.async("./some-file.js").then(result => {36 37});38 39// Load and add the prefix asynchronously with promises:40myOperation.errback("./some-file.js", (err, result) => {41 42});43```44 45This could even be exposed as your official API by doing46```js47// Using the common 'Sync' suffix for sync functions, and 'Async' suffix for48// promise-returning versions.49exports.myOperationSync = myOperation.sync;50exports.myOperationAsync = myOperation.async;51exports.myOperation = myOperation.errback;52```53or potentially expose one of the async versions as the default, with a54`.sync` property on the function to expose the synchronous version.55```js56module.exports = myOperation.errback;57module.exports.sync = myOperation.sync;58````59 60 61## API62 63### gensync(generatorFnOrOptions)64 65Returns a function that can be "await"-ed in another `gensync` generator66function, or executed via67 68* `.sync(...args)` - Returns the computed value, or throws.69* `.async(...args)` - Returns a promise for the computed value.70* `.errback(...args, (err, result) => {})` - Calls the callback with the computed value, or error.71 72 73#### Passed a generator74 75Wraps the generator to populate the `.sync`/`.async`/`.errback` helpers above to76allow for evaluation of the generator for the final value.77 78##### Example79 80```js81const readFile = function* () {82  return 42;83};84 85const readFileAndMore = gensync(function* (){86  const val = yield* readFile();87  return 42 + val;88});89 90// In general cases91const code = readFileAndMore.sync("./file.js", "utf8");92readFileAndMore.async("./file.js", "utf8").then(code => {})93readFileAndMore.errback("./file.js", "utf8", (err, code) => {});94 95// In a generator being called indirectly with .sync/.async/.errback96const code = yield* readFileAndMore("./file.js", "utf8");97```98 99 100#### Passed an options object101 102* `opts.sync`103 104  Example: `(...args) => 4`105 106  A function that will be called when `.sync()` is called on the `gensync()`107  result, or when the result is passed to `yield*` in another generator that108  is being run synchronously.109 110  Also called for `.async()` calls if no async handlers are provided.111 112* `opts.async`113 114  Example: `async (...args) => 4`115 116  A function that will be called when `.async()` or `.errback()` is called on117  the `gensync()` result, or when the result is passed to `yield*` in another118  generator that is being run asynchronously.119 120* `opts.errback`121 122  Example: `(...args, cb) => cb(null, 4)`123 124  A function that will be called when `.async()` or `.errback()` is called on125  the `gensync()` result, or when the result is passed to `yield*` in another126  generator that is being run asynchronously.127 128  This option allows for simpler compatibility with many existing Node APIs,129  and also avoids introducing the extra even loop turns that promises introduce130  to access the result value.131 132* `opts.name`133 134  Example: `"readFile"`135 136  A string name to apply to the returned function. If no value is provided,137  the name of `errback`/`async`/`sync` functions will be used, with any138  `Sync` or `Async` suffix stripped off. If the callback is simply named139  with ES6 inference (same name as the options property), the name is ignored.140 141* `opts.arity`142 143  Example: `4`144 145  A number for the length to set on the returned function. If no value146  is provided, the length will be carried over from the `sync` function's147  `length` value.148 149##### Example150 151```js152const readFile = gensync({153  sync: fs.readFileSync,154  errback: fs.readFile,155});156 157const code = readFile.sync("./file.js", "utf8");158readFile.async("./file.js", "utf8").then(code => {})159readFile.errback("./file.js", "utf8", (err, code) => {});160```161 162 163### gensync.all(iterable)164 165`Promise.all`-like combinator that works with an iterable of generator objects166that could be passed to `yield*` within a gensync generator.167 168#### Example169 170```js171const loadFiles = gensync(function* () {172  return yield* gensync.all([173    readFile("./one.js"),174    readFile("./two.js"),175    readFile("./three.js"),176  ]);177});178```179 180 181### gensync.race(iterable)182 183`Promise.race`-like combinator that works with an iterable of generator objects184that could be passed to `yield*` within a gensync generator.185 186#### Example187 188```js189const loadFiles = gensync(function* () {190  return yield* gensync.race([191    readFile("./one.js"),192    readFile("./two.js"),193    readFile("./three.js"),194  ]);195});196```197