sourav-das/stem-separator
3
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 