You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this examples Ys are being processed before Xs, but were stringified in the opposite order.
202
202
This means the internal queue of Xs grows to 10.000 before it is being processed by the second loop.
203
203
This can be avoided by changing the order to match the stringification order.
204
204
205
-
### Eager and Lazy Promises
206
-
Special attention has to be given single values, as Promises in JS have no concept of "pulling" data.
207
-
`JSONParseNexus` provides two separate methods to request a single value: `.eager` and `.lazy`.
208
-
Both return promises that resolve with the requested value, but they differ in their effect on the internal stream:
209
-
The former starts pulling values from the stream immediately until the requested value is found,
210
-
while the later will only resolve if another consumer advances the parser's cursor beyond the point where the requested value is located.
211
-
212
-
Both approaches have their pitfalls.
213
-
Requesting a value eager might parse an arbitrary amount of JSON, fill up queues and remove other's consumers ability to control the pace of data.
214
-
Requesting values lazily on the other hand might block execution entirely.
215
-
216
-
TODO: Find a better solution. Perhaps pull as part of `.then` call??
205
+
### Single Values and Lazy Promises
206
+
Special attention has to be given single values, as Promises in JS are eager by default and have no concept of "pulling" data.
207
+
`JSONParseNexus` introduces a lazy promise type that has a different behavior.
208
+
As with async iterables and streams provided by `.iterable` and `.stream`, it does not pull values form the underlying readable until requested. This happens when `await`ing the promise, i.e. is calling the `.then` instance method, otherwise it stays idle.
217
209
218
210
```js
219
-
constctrl=newJSONParseNexus();
211
+
constparser=newJSONParseNexus();
220
212
221
213
jsonStringifyStream({
222
214
type:'items',
223
215
items:newArray(10_000).fill({ x:'x' }),
224
216
trailer:'trail',
225
-
}).pipeThrough(ctrl)
217
+
}).pipeThrough(parser)
226
218
227
219
constdata= {
228
-
type:ctrl.eager('$.type') //Fine
229
-
items:ctrl.iterable('$.items.*')// Fine
230
-
trailer:ctrl.lazy('$.trailer')
220
+
type:awaitparser.promise('$.type') //ok
221
+
items:parser.iterable('$.items.*')
222
+
trailer:parser.promise('$.trailer')// do not await!
231
223
}
232
224
233
-
consttype=awaitdata.type
234
-
forawait (constxofdata.items) console.log(x)
235
-
consttrailer=awaitdata.trailer.pull()
236
-
```
237
-
238
-
In this example the use of `.eager` has unintended consequences. TBC
239
-
240
-
<!-- ```js
241
-
const ctrl = new JSONParseNexus();
225
+
console.log(data.type) //=> 'items'
242
226
243
-
const data = {
244
-
type: ctrl.lazy('$.type') // Fine
245
-
items: ctrl.iterable('$.items.*') // Fine
246
-
trailer: ctrl.lazy('$.trailer') // Oh-Oh
227
+
// Now async iteration is in control of parser:
228
+
forawait (constxofdata.items) {
229
+
console.log(x)
247
230
}
231
+
// Now we can await the trailer:
232
+
console.log(awaitdata.trailer)
233
+
```
248
234
249
-
jsonStringifyStream({
250
-
type: 'items',
251
-
items: new Array(10_000).fill({ x: 'x' }),
252
-
trailer: 'trail',
253
-
}).pipeThrough(ctrl)
254
-
255
-
const type = await data.type.pull()
256
-
for await (const x of data.items) console.log(x)
257
-
const trailer = await data.trailer.pull()
258
-
``` -->
259
-
260
-
261
-
<!-- Note that there are many pitfalls with this feature.
262
-
~~Internally, `.stream` and `.iterable` tee the object stream and filter for the requested JSON paths.~~
263
-
Internally `JSONParseNexus` manages multiple queues that it fills i
264
-
This means memory usage can grow arbitrary large if the values aren't consumed in the same order as they arrive
265
-
(TODO: actually, the queue grows large the main .readable isn't consumed. Could fix with some trickery. Maybe last call to `stream` doesn't tee the value?) -->
266
-
267
-
<!-- ~~Note that `.promise` by itself does not pull values from the stream. If it isn't combined with `pipeTo` or similar, it will never resolve.~~
268
-
~~If it is awaited before sufficient values have been pulled form the stream it will never resolve!~~ -->
235
+
In the above example, without lazy promises `ctrl.promise('$.trailer')` would immediately parse the entire JSON structure, which involves filling a queue of 10.000 elements.
269
236
270
-
<!-- Note that the promise might resolve with `undefined` if the corresponding JSON path is not found in the stream. -->
237
+
In order to transform value without triggering executions,
238
+
the class provides a `.map` function that works similar to JS arrays:
0 commit comments