mirror of
https://github.com/denoland/deno.git
synced 2024-11-22 15:06:54 -05:00
feat(core): support AbortSignal in readFile (#10943)
This commit is contained in:
parent
9c0b41e24b
commit
20b0a5125a
4 changed files with 53 additions and 9 deletions
19
cli/dts/lib.deno.ns.d.ts
vendored
19
cli/dts/lib.deno.ns.d.ts
vendored
|
@ -861,6 +861,15 @@ declare namespace Deno {
|
|||
mode?: number;
|
||||
}
|
||||
|
||||
export interface ReadFileOptions {
|
||||
/**
|
||||
* An abort signal to allow cancellation of the file read operation.
|
||||
* If the signal becomes aborted the readFile operation will be stopped
|
||||
* and the promise returned will be rejected with an AbortError.
|
||||
*/
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if a given resource id (`rid`) is a TTY.
|
||||
|
@ -1385,7 +1394,10 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readTextFile(path: string | URL): Promise<string>;
|
||||
export function readTextFile(
|
||||
path: string | URL,
|
||||
options?: ReadFileOptions,
|
||||
): Promise<string>;
|
||||
|
||||
/** Synchronously reads and returns the entire contents of a file as an array
|
||||
* of bytes. `TextDecoder` can be used to transform the bytes to string if
|
||||
|
@ -1411,7 +1423,10 @@ declare namespace Deno {
|
|||
* ```
|
||||
*
|
||||
* Requires `allow-read` permission. */
|
||||
export function readFile(path: string | URL): Promise<Uint8Array>;
|
||||
export function readFile(
|
||||
path: string | URL,
|
||||
options?: ReadFileOptions,
|
||||
): Promise<Uint8Array>;
|
||||
|
||||
/** A FileInfo describes a file and is returned by `stat`, `lstat`,
|
||||
* `statSync`, `lstatSync`. */
|
||||
|
|
|
@ -95,3 +95,25 @@ unitTest(
|
|||
assertEquals(resourcesBefore, Deno.resources());
|
||||
},
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true } },
|
||||
async function readFileWithAbortSignal(): Promise<void> {
|
||||
const ac = new AbortController();
|
||||
queueMicrotask(() => ac.abort());
|
||||
await assertThrowsAsync(async () => {
|
||||
await Deno.readFile("cli/tests/fixture.json", { signal: ac.signal });
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true } },
|
||||
async function readTextileWithAbortSignal(): Promise<void> {
|
||||
const ac = new AbortController();
|
||||
queueMicrotask(() => ac.abort());
|
||||
await assertThrowsAsync(async () => {
|
||||
await Deno.readTextFile("cli/tests/fixture.json", { signal: ac.signal });
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
@ -110,9 +110,12 @@
|
|||
const READ_PER_ITER = 32 * 1024;
|
||||
|
||||
async function readAll(r) {
|
||||
return await readAllInner(r);
|
||||
}
|
||||
async function readAllInner(r, options) {
|
||||
const buffers = [];
|
||||
|
||||
while (true) {
|
||||
const signal = options?.signal ?? null;
|
||||
while (!signal?.aborted) {
|
||||
const buf = new Uint8Array(READ_PER_ITER);
|
||||
const read = await r.read(buf);
|
||||
if (typeof read == "number") {
|
||||
|
@ -121,6 +124,9 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (signal?.aborted) {
|
||||
throw new DOMException("The read operation was aborted.", "AbortError");
|
||||
}
|
||||
|
||||
let totalLen = 0;
|
||||
for (const buf of buffers) {
|
||||
|
@ -177,6 +183,7 @@
|
|||
write,
|
||||
writeSync,
|
||||
readAll,
|
||||
readAllInner,
|
||||
readAllSync,
|
||||
};
|
||||
})(this);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
((window) => {
|
||||
const core = window.Deno.core;
|
||||
const { open, openSync } = window.__bootstrap.files;
|
||||
const { readAll, readAllSync } = window.__bootstrap.io;
|
||||
const { readAllInner, readAllSync } = window.__bootstrap.io;
|
||||
|
||||
function readFileSync(path) {
|
||||
const file = openSync(path);
|
||||
|
@ -16,10 +16,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
async function readFile(path) {
|
||||
async function readFile(path, options) {
|
||||
const file = await open(path);
|
||||
try {
|
||||
const contents = await readAll(file);
|
||||
const contents = await readAllInner(file, options);
|
||||
return contents;
|
||||
} finally {
|
||||
file.close();
|
||||
|
@ -36,10 +36,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
async function readTextFile(path) {
|
||||
async function readTextFile(path, options) {
|
||||
const file = await open(path);
|
||||
try {
|
||||
const contents = await readAll(file);
|
||||
const contents = await readAllInner(file, options);
|
||||
return core.decode(contents);
|
||||
} finally {
|
||||
file.close();
|
||||
|
|
Loading…
Reference in a new issue