mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
BREAKING CHANGE: rename Deno.toAsyncIterator() to Deno.iter() (#4848)
* rename Deno.toAsyncIterator() to Deno.iter() * adds sync version Deno.iterSync() * adds optional second argument for buffer size
This commit is contained in:
parent
da6819a14c
commit
68d287eed5
6 changed files with 169 additions and 28 deletions
|
@ -42,7 +42,8 @@ export { FsEvent, fsEvents } from "./ops/fs_events.ts";
|
|||
export {
|
||||
EOF,
|
||||
copy,
|
||||
toAsyncIterator,
|
||||
iter,
|
||||
iterSync,
|
||||
SeekMode,
|
||||
Reader,
|
||||
SyncReader,
|
||||
|
|
45
cli/js/io.ts
45
cli/js/io.ts
|
@ -84,23 +84,32 @@ export async function copy(dst: Writer, src: Reader): Promise<number> {
|
|||
return n;
|
||||
}
|
||||
|
||||
export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> {
|
||||
const b = new Uint8Array(1024);
|
||||
return {
|
||||
[Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array> {
|
||||
return this;
|
||||
},
|
||||
export async function* iter(
|
||||
r: Reader,
|
||||
bufSize?: number
|
||||
): AsyncIterableIterator<Uint8Array> {
|
||||
const b = new Uint8Array(bufSize ?? 1024);
|
||||
while (true) {
|
||||
const result = await r.read(b);
|
||||
if (result === EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
async next(): Promise<IteratorResult<Uint8Array>> {
|
||||
const result = await r.read(b);
|
||||
if (result === EOF) {
|
||||
return { value: new Uint8Array(), done: true };
|
||||
}
|
||||
|
||||
return {
|
||||
value: b.subarray(0, result),
|
||||
done: false,
|
||||
};
|
||||
},
|
||||
};
|
||||
yield b.subarray(0, result);
|
||||
}
|
||||
}
|
||||
|
||||
export function* iterSync(
|
||||
r: SyncReader,
|
||||
bufSize?: number
|
||||
): IterableIterator<Uint8Array> {
|
||||
const b = new Uint8Array(bufSize ?? 1024);
|
||||
while (true) {
|
||||
const result = r.readSync(b);
|
||||
if (result === EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
yield b.subarray(0, result);
|
||||
}
|
||||
}
|
||||
|
|
54
cli/js/lib.deno.ns.d.ts
vendored
54
cli/js/lib.deno.ns.d.ts
vendored
|
@ -573,13 +573,61 @@ declare namespace Deno {
|
|||
*/
|
||||
export function copy(dst: Writer, src: Reader): Promise<number>;
|
||||
|
||||
/** Turns a Reader, `r`, into an async iterator.
|
||||
/** **UNSTABLE**: new API, yet to be vetted
|
||||
* Turns a Reader, `r`, into an async iterator.
|
||||
*
|
||||
* for await (const chunk of toAsyncIterator(reader)) {
|
||||
* let f = await open("/etc/passwd");
|
||||
* for await (const chunk of iter(f)) {
|
||||
* console.log(chunk);
|
||||
* }
|
||||
* f.close();
|
||||
*
|
||||
* Second argument can be used to tune size of a buffer.
|
||||
* Default size of the buffer is 1024 bytes.
|
||||
*
|
||||
* let f = await open("/etc/passwd");
|
||||
* for await (const chunk of iter(f, 1024 * 1024)) {
|
||||
* console.log(chunk);
|
||||
* }
|
||||
* f.close();
|
||||
*
|
||||
* Iterator uses internal buffer of fixed size for efficiency returning
|
||||
* a view on that buffer on each iteration. It it therefore callers
|
||||
* responsibility to copy contents of the buffer if needed; otherwise
|
||||
* next iteration will overwrite contents of previously returned chunk.
|
||||
*/
|
||||
export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array>;
|
||||
export function iter(
|
||||
r: Reader,
|
||||
bufSize?: number
|
||||
): AsyncIterableIterator<Uint8Array>;
|
||||
|
||||
/** **UNSTABLE**: new API, yet to be vetted
|
||||
* Turns a SyncReader, `r`, into an iterator.
|
||||
*
|
||||
* let f = await open("/etc/passwd");
|
||||
* for (const chunk of iterSync(reader)) {
|
||||
* console.log(chunk);
|
||||
* }
|
||||
* f.close();
|
||||
*
|
||||
* Second argument can be used to tune size of a buffer.
|
||||
* Default size of the buffer is 1024 bytes.
|
||||
*
|
||||
* let f = await open("/etc/passwd");
|
||||
* for (const chunk of iterSync(reader, 1024 * 1024)) {
|
||||
* console.log(chunk);
|
||||
* }
|
||||
* f.close()
|
||||
*
|
||||
* Iterator uses internal buffer of fixed size for efficiency returning
|
||||
* a view on that buffer on each iteration. It it therefore callers
|
||||
* responsibility to copy contents of the buffer if needed; otherwise
|
||||
* next iteration will overwrite contents of previously returned chunk.
|
||||
*/
|
||||
export function iterSync(
|
||||
r: SyncReader,
|
||||
bufSize?: number
|
||||
): IterableIterator<Uint8Array>;
|
||||
|
||||
/** Synchronously open a file and return an instance of `Deno.File`. The
|
||||
* file does not need to previously exist if using the `create` or `createNew`
|
||||
|
|
|
@ -25,23 +25,71 @@ unitTest({ perms: { read: true } }, async function filesCopyToStdout(): Promise<
|
|||
file.close();
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, async function filesIter(): Promise<void> {
|
||||
const filename = "cli/tests/hello.txt";
|
||||
const file = await Deno.open(filename);
|
||||
|
||||
let totalSize = 0;
|
||||
for await (const buf of Deno.iter(file)) {
|
||||
totalSize += buf.byteLength;
|
||||
}
|
||||
|
||||
assertEquals(totalSize, 12);
|
||||
file.close();
|
||||
});
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true } },
|
||||
async function filesToAsyncIterator(): Promise<void> {
|
||||
async function filesIterCustomBufSize(): Promise<void> {
|
||||
const filename = "cli/tests/hello.txt";
|
||||
const file = await Deno.open(filename);
|
||||
|
||||
let totalSize = 0;
|
||||
for await (const buf of Deno.toAsyncIterator(file)) {
|
||||
let iterations = 0;
|
||||
for await (const buf of Deno.iter(file, 6)) {
|
||||
totalSize += buf.byteLength;
|
||||
iterations += 1;
|
||||
}
|
||||
|
||||
assertEquals(totalSize, 12);
|
||||
assertEquals(iterations, 2);
|
||||
file.close();
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(async function readerToAsyncIterator(): Promise<void> {
|
||||
unitTest({ perms: { read: true } }, function filesIterSync(): void {
|
||||
const filename = "cli/tests/hello.txt";
|
||||
const file = Deno.openSync(filename);
|
||||
|
||||
let totalSize = 0;
|
||||
for (const buf of Deno.iterSync(file)) {
|
||||
totalSize += buf.byteLength;
|
||||
}
|
||||
|
||||
assertEquals(totalSize, 12);
|
||||
file.close();
|
||||
});
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true } },
|
||||
function filesIterSyncCustomBufSize(): void {
|
||||
const filename = "cli/tests/hello.txt";
|
||||
const file = Deno.openSync(filename);
|
||||
|
||||
let totalSize = 0;
|
||||
let iterations = 0;
|
||||
for (const buf of Deno.iterSync(file, 6)) {
|
||||
totalSize += buf.byteLength;
|
||||
iterations += 1;
|
||||
}
|
||||
|
||||
assertEquals(totalSize, 12);
|
||||
assertEquals(iterations, 2);
|
||||
file.close();
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(async function readerIter(): Promise<void> {
|
||||
// ref: https://github.com/denoland/deno/issues/2330
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
|
@ -69,7 +117,42 @@ unitTest(async function readerToAsyncIterator(): Promise<void> {
|
|||
const reader = new TestReader("hello world!");
|
||||
|
||||
let totalSize = 0;
|
||||
for await (const buf of Deno.toAsyncIterator(reader)) {
|
||||
for await (const buf of Deno.iter(reader)) {
|
||||
totalSize += buf.byteLength;
|
||||
}
|
||||
|
||||
assertEquals(totalSize, 12);
|
||||
});
|
||||
|
||||
unitTest(async function readerIterSync(): Promise<void> {
|
||||
// ref: https://github.com/denoland/deno/issues/2330
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
class TestReader implements Deno.SyncReader {
|
||||
#offset = 0;
|
||||
#buf: Uint8Array;
|
||||
|
||||
constructor(s: string) {
|
||||
this.#buf = new Uint8Array(encoder.encode(s));
|
||||
}
|
||||
|
||||
readSync(p: Uint8Array): number | Deno.EOF {
|
||||
const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset);
|
||||
p.set(this.#buf.slice(this.#offset, this.#offset + n));
|
||||
this.#offset += n;
|
||||
|
||||
if (n === 0) {
|
||||
return Deno.EOF;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
const reader = new TestReader("hello world!");
|
||||
|
||||
let totalSize = 0;
|
||||
for await (const buf of Deno.iterSync(reader)) {
|
||||
totalSize += buf.byteLength;
|
||||
}
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ class Body implements domTypes.Body, ReadableStream<Uint8Array>, io.ReadCloser {
|
|||
}
|
||||
|
||||
[Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array> {
|
||||
return io.toAsyncIterator(this);
|
||||
return io.iter(this);
|
||||
}
|
||||
|
||||
get bodyUsed(): boolean {
|
||||
|
|
|
@ -164,7 +164,7 @@ export async function writeChunkedBody(
|
|||
r: Deno.Reader
|
||||
): Promise<void> {
|
||||
const writer = BufWriter.create(w);
|
||||
for await (const chunk of Deno.toAsyncIterator(r)) {
|
||||
for await (const chunk of Deno.iter(r)) {
|
||||
if (chunk.byteLength <= 0) continue;
|
||||
const start = encoder.encode(`${chunk.byteLength.toString(16)}\r\n`);
|
||||
const end = encoder.encode("\r\n");
|
||||
|
|
Loading…
Add table
Reference in a new issue