上传进度取消
通过 type 判断
const OPERATE_TYPE = {
COMPLETE: '完成',
CANCEL: '取消',
};
const promiseTimeout = seconds => new Promise((resolve) => {
let time = seconds || Math.floor(Math.random() * 10)
setTimeout(() => {
resolve()
}, time * 1000);
})
const promiseUpload = new Promise(async (resolve) => {
await promiseTimeout();
resolve({
type: OPERATE_TYPE.COMPLETE,
message: '上传已完成',
});
})
const promiseCancel = new Promise(async (resolve) => {
await promiseTimeout();
resolve({
type: OPERATE_TYPE.CANCEL,
message: '上传已取消',
});
})
Promise.race([promiseUpload, promiseCancel]).then((result) => {
const { type, message } = result;
switch (type) {
case OPERATE_TYPE.COMPLETE:
break;
case OPERATE_TYPE.CANCEL:
break;
default:
break;
}
console.log(message)
}).catch((error) => {
console.log(error)
})
通过 promise 状态判断
const promiseTimeout = seconds => new Promise((resolve) => {
let time = seconds || Math.floor(Math.random() * 10)
setTimeout(() => {
resolve()
}, time * 1000);
})
const promiseUpload = new Promise(async (resolve) => {
await promiseTimeout();
resolve('上传已完成');
})
const promiseCancel = new Promise(async (resolve, reject) => {
await promiseTimeout();
reject('上传已取消');
})
const doUpload = () => new Promise((resolve, reject) =>
Promise.race([promiseUpload, promiseCancel]).then((message) => {
resolve(message)
}).catch((error) => {
reject(error)
})
)
doUpload().then(msg => {
console.log(msg);
}).catch(error => {
console.log(error);
}).finally(() => {
console.log('upload done');
});
通过 AbortController 取消
import { useState, useEffect } from 'react';
function assertIsCharacter(data) {
if (!('name' in data)) {
throw new Error('Not character');
}
}
const STATUS_LIST = {
LOADING: 'loading',
LOADED: 'loaded',
CANCElLD: 'cancelled',
};
export default function Abort() {
const [status, setStatus] = useState(STATUS_LIST.LOADING);
const [data, setData] = useState(undefined);
const [query, setQuery] = useState(undefined);
let cancel = () => {};
function getCharacter(id) {
const controller = new AbortController();
const { signal } = controller;
const promise = new Promise(async (resolve) => {
const response = await fetch(`https://swapi.dev/api/people/${id}/`, {
method: 'get',
signal,
});
const data = await response.json();
assertIsCharacter(data);
resolve(data);
});
cancel = () => controller.abort();
return promise;
}
useEffect(() => {
const q = getCharacter(1);
setQuery(q);
q.then((character) => {
setData(character);
setStatus(STATUS_LIST.LOADED);
});
}, [null]);
const handleCancel = () => {
if (query) {
cancel();
setStatus(STATUS_LIST.CANCElLD);
}
};
if (status === STATUS_LIST.LOADING) {
return (
<div>
<div>loading ...</div>
<button onClick={handleCancel}>Cancel</button>
</div>
);
}
if (status === STATUS_LIST.CANCElLD) {
return <div>Cancelled</div>;
}
return <div>{data && <h3>{data.name}</h3>}</div>;
}