你好,我是TianTian。
卷友们,周末好呀!大家周末要怎么卷过去呢。
想着马上要秋招了,大家肯定在加急准备秋招,今天给大家分享一篇不错的Promise面试知识点梳理
。说不定对你有一些帮助。
编者注解
这是作者鼠子的寄语:
本文旨在使用一个易于理解、易于记忆的方式去吃透promise相关应用侧的技术点,从而应用于简历和面试中。
比起其他大佬的文章,本文更注重于实战性,同时也会尽可能的去提高代码规范和质量(个人水平受限无法给出最优解)。俗话说的好,贪多嚼不烂,想要深入了解更多实现方法和细节的同学可以补充看更多更加优秀的文章。
超时控制
背景
众所周知,fetch请求是无法设置超时时间的,因此我们需要自己去模拟一个超时控制。
转盘问题,一个抽奖转盘动画效果有5秒,但是一般来说向后端请求转盘结果只需要不到一秒,因此请求结果至少得等5秒才能展现给用户。
问题分析
首先,超时控制比较简单,和Promise.race()的思想是类似,或者可以直接使用这个函数去解决。
然后,转盘问题如果要答好,需要考虑两种情况。
转盘动画还未完成,请求结果已经拿到了,此时要等到动画完成再展示结果给用户。
转盘动画完成了,请求结果还未拿到,此时需要等待结果返回(可以设置请求超时时间)。
所以,转盘问题更适合用Promise.all()来解决。
实战版源码
代码分为多个版本,从上自下,记忆难度递增但面试成绩更优,请按需选择。
一、基于Promise.race()
的超时控制。
/**
* 超时控制版本一
*/
/**
* 辅助函数,封装一个延时promise
* @param {number} delay 延迟时间
* @returns {Promise<any>}
*/
function sleep(delay) {
return new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("timeout")), delay);
});
}
/**
* 将原promise包装成一个带超时控制的promise
* @param {()=>Promise<any>} requestFn 请求函数
* @param {number} timeout 最大超时时间
* @returns {Promise<any>}
*/
function timeoutPromise(requestFn, timeout) {
return Promise.race([requestFn(), sleep(timeout)]);
}
// ----------下面是测试用例------------
// 模拟一个异步请求函数
function createRequest(delay) {
return () =>
new Promise((resolve) => {
setTimeout(() => {
resolve("done");
}, delay);
});
}
// 超时的例子
timeoutPromise(createRequest(2000), 1000).catch((error) =>
console.error(error)
);
// 不超时的例子
timeoutPromise(createRequest(2000), 3000).then((res) => console.log(res));
复制代码
二、将promise.race()
干掉。
/**
* 超时控制版本二
*/
/**
* 辅助函数,封装一个延时promise
* @param {number} delay 延迟时间
* @returns {Promise<any>}
*/
function sleep(delay) {
return new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("timeout")), delay);
});
}
/**
* 将原promise包装成一个带超时控制的promise
* @param {()=>Promise<any>} requestFn 请求函数
* @param {number} timeout 最大超时时间
* @returns {Promise<any>}
*/
function timeoutPromise(requestFn, timeout) {
const promises = [requestFn(), sleep(timeout)];
return new Promise((resolve, reject) => {
for (