闽公网安备 35020302035485号
一.前言
阅读本文,你将学到:
1. 学会如何实现一个比较完善的 delay 函数4. 等等
# 推荐克隆我的项目,保证与文章同步 git clone https://github.com/lxchuan12/delay-analysis.git # npm i -g yarn cd delay-analysis/delay && yarn i # VSCode 直接打开当前项目 # code . # 我写的例子都在 examples 这个文件夹中,可以启动服务本地查看调试 # 在 delay-analysis 目录下 npx http-server examples # 打开 http://localhost:8080 # 或者克隆官方项目 git clone https://github.com/sindresorhus/delay.git # npm i -g yarn cd delay && yarn i # VSCode 直接打开当前项目 # code .三. delay
(async() => {
await delay1(1000);
console.log('输出这句');
})();
3.1.2 实现const delay1 = (ms) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});
}
我们要传递结果。(async() => {
const result = await delay2(1000, { value: '我是若川' });
console.log('输出结果', result);
})();
我们也很容易实现如下代码。传递 value 最后作为结果返回。const delay2 = (ms, { value } = {}) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(value);
}, ms);
});
}
这样写,Promise 永远是成功。我们也需要失败。这时我们定义个参数 willResolve 来定义。(async() => {
try{
const result = await delay3(1000, { value: '我是若川', willResolve: false });
console.log('永远不会输出这句');
}
catch(err){
console.log('输出结果', err);
}
})();
3.3.2 实现// 堆代码 duidaima.com
const delay3 = (ms, {value, willResolve} = {}) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(willResolve){
resolve(value);
}
else{
reject(value);
}
}, ms);
});
}
3.4 第四版 一定时间范围内随机获得结果(async() => {
try{
const result = await delay4.reject(1000, { value: '我是若川', willResolve: false });
console.log('永远不会输出这句');
}
catch(err){
console.log('输出结果', err);
}
const result2 = await delay4.range(10, 20000, { value: '我是若川,range' });
console.log('输出结果', result2);
})();
3.4.2 实现const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum);
const createDelay = ({willResolve}) => (ms, {value} = {}) => {
return new Promise((relove, reject) => {
setTimeout(() => {
if(willResolve){
relove(value);
}
else{
reject(value);
}
}, ms);
});
}
const createWithTimers = () => {
const delay = createDelay({willResolve: true});
delay.reject = createDelay({willResolve: false});
delay.range = (minimum, maximum, options) => delay(randomInteger(minimum, maximum), options);
return delay;
}
const delay4 = createWithTimers();
实现到这里,相对比较完善了。但我们可能有需要提前结束。(async () => {
const delayedPromise = delay5(1000, {value: '我是若川'});
setTimeout(() => {
delayedPromise.clear();
}, 300);
// 300 milliseconds later
console.log(await delayedPromise);
//=> '我是若川'
})();
3.5.2 实现const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum);
const createDelay = ({willResolve}) => (ms, {value} = {}) => {
let timeoutId;
let settle;
const delayPromise = new Promise((resolve, reject) => {
settle = () => {
if(willResolve){
resolve(value);
}
else{
reject(value);
}
}
timeoutId = setTimeout(settle, ms);
});
delayPromise.clear = () => {
clearTimeout(timeoutId);
timeoutId = null;
settle();
};
return delayPromise;
}
const createWithTimers = () => {
const delay = createDelay({willResolve: true});
delay.reject = createDelay({willResolve: false});
delay.range = (minimum, maximum, options) => delay(randomInteger(minimum, maximum), options);
return delay;
}
const delay5 = createWithTimers();
3.6 第六版 取消功能caniuse AbortController[4] npm abort-controller[5] mdn AbortController[6] fetch-abort[7] fetch#aborting-requests[8] yet-another-abortcontroller-polyfill[9]3.6.1 使用
(async () => {
const abortController = new AbortController();
setTimeout(() => {
abortController.abort();
}, 500);
try {
await delay6(1000, {signal: abortController.signal});
} catch (error) {
// 500 milliseconds later
console.log(error.name)
//=> 'AbortError'
}
})();
3.6.2 实现const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum);
const createAbortError = () => {
const error = new Error('Delay aborted');
error.name = 'AbortError';
return error;
};
const createDelay = ({willResolve}) => (ms, {value, signal} = {}) => {
if (signal && signal.aborted) {
return Promise.reject(createAbortError());
}
let timeoutId;
let settle;
let rejectFn;
const signalListener = () => {
clearTimeout(timeoutId);
rejectFn(createAbortError());
}
const cleanup = () => {
if (signal) {
signal.removeEventListener('abort', signalListener);
}
};
const delayPromise = new Promise((resolve, reject) => {
settle = () => {
cleanup();
if (willResolve) {
resolve(value);
} else {
reject(value);
}
};
rejectFn = reject;
timeoutId = setTimeout(settle, ms);
});
if (signal) {
signal.addEventListener('abort', signalListener, {once: true});
}
delayPromise.clear = () => {
clearTimeout(timeoutId);
timeoutId = null;
settle();
};
return delayPromise;
}
const createWithTimers = () => {
const delay = createDelay({willResolve: true});
delay.reject = createDelay({willResolve: false});
delay.range = (minimum, maximum, options) => delay(randomInteger(minimum, maximum), options);
return delay;
}
const delay6 = createWithTimers();
3.7 第七版 自定义 clearTimeout 和 setTimeout 函数const customDelay = delay7.createWithTimers({clearTimeout, setTimeout});
(async() => {
const result = await customDelay(100, {value: '我是若川'});
// Executed after 100 milliseconds
console.log(result);
//=> '我是若川'
})();
3.7.2 实现 const randomInteger = (minimum, maximum) => Math.floor((Math.random() * (maximum - minimum + 1)) + minimum);
const createAbortError = () => {
const error = new Error('Delay aborted');
error.name = 'AbortError';
return error;
};
const createDelay = ({clearTimeout: defaultClear, setTimeout: set, willResolve}) => (ms, {value, signal} = {}) => {
if (signal && signal.aborted) {
return Promise.reject(createAbortError());
}
let timeoutId;
let settle;
let rejectFn;
const clear = defaultClear || clearTimeout;
const signalListener = () => {
clear(timeoutId);
rejectFn(createAbortError());
}
const cleanup = () => {
if (signal) {
signal.removeEventListener('abort', signalListener);
}
};
const delayPromise = new Promise((resolve, reject) => {
settle = () => {
cleanup();
if (willResolve) {
resolve(value);
} else {
reject(value);
}
};
rejectFn = reject;
timeoutId = (set || setTimeout)(settle, ms);
});
if (signal) {
signal.addEventListener('abort', signalListener, {once: true});
}
delayPromise.clear = () => {
clear(timeoutId);
timeoutId = null;
settle();
};
return delayPromise;
}
const createWithTimers = clearAndSet => {
const delay = createDelay({...clearAndSet, willResolve: true});
delay.reject = createDelay({...clearAndSet, willResolve: false});
delay.range = (minimum, maximum, options) => delay(randomInteger(minimum, maximum), options);
return delay;
}
const delay7 = createWithTimers();
delay7.createWithTimers = createWithTimers;
四. axios 取消请求# 推荐克隆我的项目,保证与文章同步 git clone https://github.com/lxchuan12/delay-analysis.git cd delay-analysis # 我写的例子都在 examples 这个文件夹中,可以启动服务本地查看调试 npx http-server examples # 打开 http://localhost:8080