1. HTML部分
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<button id="btn">abortbutton>
<script>
script>
body>
html>
2. JavaScript部分
1. Promise.race()
let abort = null;
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("p1");
resolve('p1');
}, 3 * 1000)
})
let p2 = new Promise((resolve, reject) => {
abort = reject;
setTimeout(() => {
console.log('p2');
resolve('p2')
}, 10 * 1000)
})
Promise.race([p1, p2]).then(res => {
console.log(res)
}).catch((err) => {
console.log(err, 'abort')
})
btn.addEventListener('click', () => {
abort('abort')
})
2. Promise.withResolvers()
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const controlPromise = (asyncFn) => {
let rejected = false;
let { promise, resolve, reject } = Promise.withResolvers();
return {
abort: () => {
rejected = true;
reject(new Error('Task abort'));
},
start: () => {
if (!rejected) {
asyncFn().then(resolve, reject);
};
return promise;
}
}
}
const task = controlPromise(async () => {
await sleep(10 * 1000);
return 'task done';
});
task.start().then(console.log, console.error);
btn.addEventListener('click', () => {
task.abort();
})
3. AbortController类
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const controlPromise = (asyncFn) => {
const abortController = new AbortController();
const signal = abortController.signal;
return {
abort: () => abortController.abort(),
start: () => {
return new Promise((resolve, reject) => {
const cancel = () => reject(new Error('Task abort'));
if (signal.aborted) {
cancel();
return;
}
asyncFn().then(resolve, reject);
signal.addEventListener('abort', cancel);
})
}
}
}
const task = controlPromise(async () => {
await sleep(10 * 1000);
return 'task done';
});
task.start().then(console.log, console.error);
btn.addEventListener('click', () => {
task.abort();
})