蓝桥杯高频知识点(上)
Posted 麻摆子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯高频知识点(上)相关的知识,希望对你有一定的参考价值。
一、进制转换
1.十进制: 都是以0-9这九个数字组成,不能以0开头。
2.二进制: 由0和1两个数字组成。
3.八进制: 由0-7数字组成,为了区分与其他进制的数字区别,开头都是以0开始。
4.十六进制:由0-9和A-F组成。为了区分于其他数字的区别,开头都是以0x开始。
1.整数转换
(1)十进制转二进制的转换原理:除以2,反向取余数,直到商为0终止。
(2)十进制转八进制的转换原理:除以8,反向取余er数,直到商为0终止。
(3)十进制转十六进制的转换原理:除以16,反向取余数,直到商为0终止。
2.小数部分转换
(1)十进制转二进制的原理:十进制小数转换成二进制小数采用 “乘2取整,顺序输出” 法。
例题: 0.68D = ______ B(精确到小数点后5位)
如下所示,0.68乘以2,取整,然后再将小数乘以2,取整,直到达到题目要求精度。得到结果:0.10101B.
例如:十进制小数0.68转换为二进制数
具体步骤:
0.68* 2=1.36 -->1
0.36* 2=0.72 -->0
0.72* 2=1.44 -->1
0.44* 2=0.88–>0
0.88* 2=1.76 -->1
已经达到了题目要求的精度,最后将取出的整数部分顺序输出即可
则为:0.68D–>0.10101B
(2)十进制转八进制的原理:十进制小数转换成八进制小数采用 “乘8取整,顺序输出” 法。
例题: 10.68D = ______ Q(精确到小数点后3位)
解析:如下图所示,整数部分除以8取余数,直到无法整除。小数部分0.68乘以8,取整,然后再将小数乘以8,取整,直到达到题目要求精度。得到结果:12.534Q.
例如:十进制数10.68转换成八进制数,分为整数部分和小数部分求解
步骤:
(1)整数部分
10/8=1 -->2
1/8=0 -->1
倒序输出为12
(2)小数部分
0.68* 8=5.44 -->5
0.44* 8=3.52 -->3
0.52* 8=4.16 -->4
已经达到了题目要求的精度,即可结束
则小数部分为:0.68–>0.534
因此10.68D -->12.534Q
(3)十进制转十六进制的原理:十进制小数转换成十六进制小数采用 “乘16取整,顺序输出” 法。
例题: 25.68D = ______ H(精确到小数点后3位) 解析:如下图所示,整数部分除以16取余数,直到无法整除。小数部分0.68乘以16,取整,然后再将小数乘以16,取整,直到达到题目要求精度。得到结果:19.ae1H.
(1)整数部分
25/16=1 -->9
1/16=0 -->1
倒序输出为:19
(2)小数部分
0.68* 16=10.88 -->a(即十进制中的10)
0.88* 16=14.08 -->e
0.08* 16=1.28 -->1
已经达到了要求的精度,顺序输出为:ae1
则:25.68D -->19.ae1H
总结:小数部分转换原理都是乘进制数取整数部分,再将整数部分顺序输出。
例题1:年号字串(十进制转换成二十六进制)——2019省赛
- 2019 / 26 = 77 余 17 ,17 对应
Q
- 77 / 26 = 2 余 25,25 对应
Y
- 2 / 26 = 0 余 2, 2 对应
B
ASCII码中:48~57为0到9十个阿拉伯数字;65~90为26个大写英文字母;97~122号为26个小写英文字母
ASCII码大写字母转换为数字:大写字母-‘A’+1 或者 大写字母-‘@’
ASCII码数字转换为大写字母:数字+‘A’-1 或者 数字+‘@’或者 数字+64
ASCII码小写字母转换为数字:小写字母-‘a’+1
ASCII码数字转换为小写字母:数字+‘a’-1
ASCII码大写字母转换为小写字母:大写字母+32 或者 大写字母-‘A’+‘a’
ASCII码小写字母转换为大写字母:小写字母-32 或者 小写字母-‘a’+‘A’
ASCII码字符型数字转换为整型数字:字符型数字 - ‘0’ 或者 字符型数字 - 48
8、ASCII码整型数字转换为字符型数字:整型数字 + 48 或者 整形数字 + ‘0’
解法1:迭代
#include <iostream>
using namespace std;
void solve(int n)
if (n==0)
return ;
solve(n / 26);
cout << (char)(n % 26 + 64);//int值65强转char会根据ASCII转成对应的字符A,
int main()
solve(2019);
return 0;
解法2:STL容器
#include <iostream>
#include <stack>
using namespace std;
stack<int> sta;
int main()
int n=2019;
while(n!=0)
sta.push(n%26);
n=n/26;
while(!sta.empty())
cout<<(char)(sta.top()+64);
//或者把加上64换成加上'@'
cout<<(char)(sta.top()+'@');
sta.pop();
return 0;
例题2:九进制转换成十进制 ——2022省赛
此题可参考二进制转换成十进制的方法
#include <iostream>
#include<stack>
#include<cmath>
using namespace std;
int main()
// 请在此输入您的代码
int n=2022;//把2,0,2,2分别传入sta中
stack<int> sta;
sta.push(n/1000);
n=n-(n/1000)*1000;
sta.push(n/100);
n=n-(n/100)*100;
sta.push(n/10);
sta.push(n-(n/10)*10);
int num=0;//2022的十进制数
int i=0;
while(!sta.empty())
i++;
//cout<<sta.top()<<" ";
num+=sta.top()*pow(9,i-1);
sta.pop();
cout<<num;
return 0;
二、模运算
取模运算也叫取余运算,在C中用%来表示, 数学中叫mod。
例题3:数列求值——2019省赛
题目要求的是第20190324位的后四位数,所以,每次计算只需要计算后四位相加的结果,这时我们可以想到对数列的每一项进行对10000取模的操作,这样即保留的是数的后四位,又不会改变它的值。
#include <iostream>
#include<vector>
using namespace std;
int main()
// 请在此输入您的代码
vector<int> vec(20190324);
vec[0]=1;
vec[1]=1;
vec[2]=1;
for(int i=3;i<20190324;i++)
vec[i]=(vec[i-3]+vec[i-2]+vec[i-1])%10000;
cout<<vec[20190323];
return 0;
三、GCD求最大公约数
如何求最大公约数?
欧几里得算法(辗转相除法)
定理1:d能整除a且d能整除b,那么d就能整除ax+by;
定理2:
证明:
a/b就是(a整除b)=c,也就是c是整数。
因为d能整除a且d能整除b,那么由定理1可得,d就能整除,那么d就能整除
求最大公约数代码:
int gcd(int a,int b)
return b?gcd(b,a%b):a;//b为真执行gcd(b,a%b);b为假执行return a
例题4:等差数列
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int gcd(int a,int b)
return b?gcd(b,a%b):a;//b为真执行gcd(b,a%b);b为假执行return a
int main()
int n,i;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++) cin>>a[i];
sort(a.begin(),a.end());//排序
int d=a[1]-a[0];
for(int i=2;i<n;i++)
d=gcd(d,a[i]-a[i-1]);
if(a[n-1]==a[0])cout<<n<<endl;//考虑特殊情况,也就是n个数都相等的情况
else cout<<((a[n-1]-a[0])/d)+1<<endl;//等差数列公式
return 0;
四、日期枚举
1.什么是闰年:
闰年一年的时间为:366天,2月份有29天。
平年一年的时间为:365天,2月份有28天。
2.闰年的判定方法:
(1)普通年能被4整除且不能被100整除的为闰年。(如2004年就是闰年,1900年不是闰年)
(2)世纪年能被400整除的是闰年。(如2000年是闰年,1900年不是闰年)
判断闰年的代码:
bool isleep(int year)
if((year%4==0&&year%100!=0)||year%400==0) return true;
else return false;
判断日期是否有效的代码:
bool isvalid(int year,int month,int day)
if(month<=0||month>12) return false;
if(day>31) return false;
if(month==2)
if(isleep(year)&&day>29) return false;//是闰年
if(!isleep(year)&&day>28) return false;//不是闰年
return true;
例题5:回文日期
#include <iostream>
using namespace std;
bool isleep(int year)
if((year%4==0&&year%100!=0)||year%400==0) return true;
else return false;
bool isvalid(int year,int month,int day)
if(month<=0||month>12) return false;
if(day>31) return false;
if(month==2)
if(isleep(year)&&day>29) return false;//是闰年
if(!isleep(year)&&day>28) return false;//不是闰年
return true;
int main()
// 请在此输入您的代码
int n;
cin>>n;
int a,b,c,d,e,f,g,h;
int year,month,day;
bool flag=false;
for(int i=n+1;i<=99999999;i++)
year=i/10000;
month=(i%10000)/100;
day=i%100;
a=i%10;
b=(i/10)%10;
c=(i/100)%10;
d=(i/1000)%10;
e=(i/10000)%10;
f=(i/100000)%10;
g=(i/1000000)%10;
h=(i/10000000)%10;//hgfedcba
if(h==a&&g==b&&f==c&&e==d&&isvalid(year,month,day)&&flag==false)
cout<<i<<endl;
flag=true;
if(a==h&&g==b&&f==c&&e==d&&h==f&&g==e&&isvalid(year,month,day))
cout<<i<<endl;
break;
return 0;
五、枚举,计算贡献
例题6:子串分值和
1.unordered_set 容器具有以下几个特性:
- 不再以键值对的形式存储数据,而是直接存储数据的值;
- 容器内部存储的各个元素的值都互不相等,自动删去重复元素,使得集合内的元素各不相同,且不能被修改;
- 不会对内部存储的数据进行排序(这和该容器底层采用哈希表结构存储数据有关;
2.unordered_set 容器的成员方法:
size() | 返回当前容器中存有元素的个数。 |
insert() | 向集合中插入某个元素。 |
emplace() | 向容器中添加新元素,效率比 insert() 方法高。 |
clear() | 清空容器,即删除容器中存储的所有元素 |
方法一:暴力枚举(只能通过40%的案例)
#include <iostream>
#include<unordered_set>
using namespace std;
int main()
// 请在此输入您的代码
string s;
cin>>s;
int n=s.length();
int res=0;
for(int l=0;l<n;l++)
for(int r=l;r<n;r++)
unordered_set<char> S;
for(int k=l;k<=r;k++) S.insert(s[k]);
res+=S.size();
cout<<res;
return 0;
方法二:乘法原理
1.每个字母只有在第一次出现时才有f值(也叫贡献度),因此可以统计每个字母在第一次出现的情况下,能被多少子串所包含;
2.用 记录字母 s[i] 上一次出现的位置;
3.那么往左最多能延伸到,其到第 i 个字母一共有个字母;同理往右最多能延伸到 n,其到第 i 个字母一共有 个字母;
4.二者相乘,就是该字母被不同子串所包含的总次数;
那么该如何来计算每个字符的贡献度呢?所谓贡献度,即该字符能够影响到的子串个数,就比如:
0 | 1 | 2 | 3 | 4 | 5 |
a | b | a | b | c |
表格中的4号b能够影响多少个子串呢?
列举一下有:ab,b,abc,bc共有4个(这些子串的f值都因为b增加了1,而bab这个子串不会因为3号b增加f值).
那么如何用数学的方法计算出来贡献度呢?
b上次出现的位置是,i是现在这个b在的位置,,所以这些子串的起点可以为3,4,也就是往左最多能延伸到;终点往右最多能延伸到 (n是字符串的长度),终点可以为4,5,这样该字母b被不同子串所包含的总次数即(4-2)*(5-4+1) = 4
表格中的3号a能影响多少子串呢?列举一下有;ba,bab,babc,a,ab,abc
起点可以是2,3;终点可以是3,4,5,所以该字母a被不同子串所包含的总次数即(3-1)*(5-3+1) =6
a,出现在 a,ab,aba,abab,ababc中,对每一个串贡献值为1,和为5,
b,出现在b,ba,bab,babc+ab,aba,abac,ababc,对每一个串贡献值为1,和为8
a,出现在a,ab,abc + ba,bab,babc + aba,abab,ababc,有重复子串 aba,abab,ababc(这几个其实第一个a已经包含过它们了,所以只需要从a算到b a,前面的可以删去不用,因为之前的情况前面的a已经贡献过了),最后算得贡献值为6,
b,出现在了b,bc + ab,abc +bab,babc + abab,ababc,含有相同字符的前串bab ,babc,abab,ababc可以去掉,最后算得贡献值为4,
c,出现在c,bc,abc,babc,ababc对每一个串贡献值为1,和为5
答案就是: 5 + 8 + 6 + 4 + 5 = 28
六、动态规划之线性DP
例题7:数字三角形
#include <iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
// 递推公式dp[i][j]=max(dp[i-1][j-1]+a[i][j],dp[i-1][j]+a[i][j])
int N;
cin>>N;
vector<vector<int>> a(N,vector<int>(N));
vector<vector<int>> dp(N,vector<int>(N));
for(int i=0;i<N;i++)//行
for(int j=0;j<i+1;j++)
cin>>a[i][j];
dp[0][0]=a[0][0];
for(int i=1;i<N;i++)//行
for(int j=0;j<=i;j++)//列
if(j==0) dp[i][0]=dp[i-1][0]+a[i][0];//左斜边
else if(j==i) dp[i][j]=dp[i-1][j-1]+a[i][j];//右斜边
else dp[i][j]=max(dp[i-1][j-1]+a[i][j],dp[i-1][j]+a[i][j]);
cout<<*max_element(dp[N-1].begin(),dp[N-1].end());
// int res=0;
// for(int j=0;j<N;j++) res=max(res,dp[N-1][j]);
// cout<<res;
return 0;
七、动态规划之偏移量
例题8:砝码称重
#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll N;
ll a[200];
ll summ = 0;
ll ans = 0;
int dp[200][200000];
//dp[i][j]表示用到前i个砝码,能否称出j重量
//1为可以,0为不可以
int main()
// 请在此输入您的代码
cin >> N;
for (int i = 1; i <= N; i++)
cin >> a[i];
summ += a[i];
for (int i = 1; i <= N; i++)
for (int j = 1; j <= summ; j++)
dp[i][j] = dp[i - 1][j];//继承前一个状态
if (dp[i][j] == 0)
if (j == a[i]) dp[i][j] = 1;//如果需要的重量正好就是第i个砝码,那么可以
if (dp[i - 1][j + a[i]] == 1) dp[i][j] = 1;//如果前i-1个能搞出j+a[i]重量,那么把第i个砝码放到另一侧就行
if (dp[i - 1][abs(j - a[i])] == 1) dp[i][j] = 1;//如果前i-1个砝码能搞出abs(j-a[i])重量
//那么把第i个砝码放同侧就行
for (int j = 1; j <= summ; j++)
if (dp[N][j] == 1) ans++;//遍历,看dp[][]==1的个数,就是答案
cout << ans << endl;
return 0;
八、因子分解
比如:18=2×3×3=2×3^2。约数有1,2,3,6,9,18,约数个数为(1+1)×(2+1)。
为什么要加1:因为对于2×3^2来说。2这个位置有两种选择(0,1),3这个位置有三种选择(0,1,2);18的约数之和就是
求约数个数的代码:
int get_an(int x)//求x的约数个数
unordered_map<int, int> primes;//i放质因数,primes[i]放对应的质因数的个数
int res=1;
for(int i=2;i<=x/i;i++)
while (x % i == 0)//说明i是x的质约数
x=x/i;
primes[i]++;//i是质因子,primes[i]是指数
if(x>1) primes[x]++;
//for(auto p:primes) cout<<p.first<<" "<<p.second<<endl;
for(auto p:primes) res=res*(p.second+1);
cout<<res<<endl;
求约数的和的代码:
int get_an(int x)//求x的约数的和
unordered_map<int, int> primes;//i放质因数,primes[i]放对应的质因数的个数
for(int i=2;i<=x/i;i++)
while (x % i == 0)//说明i是x的质约数
x=x/i;
primes[i]++;//i是质因子,primes[i]是指数
if(x>1) primes[x]++;
//for(auto p:primes) cout<<p.first<<" "<<p.second<<endl;
vector<int> vec;
for(auto p:primes)
int sum=0;
for(int j=0;j<=p.second;j++)
sum+=pow(p.first,j);
vec.push_back(sum);
int ans=1;//ans是最后的总和
for(int i=0;i<vec.size();i++) ans*=vec[i];
cout<<res<<endl;
例题9:约数个数
#include <iostream>
#include<unordered_map>
using namespace std;
int main()
int x=1200000;
int res=1;
unordered_map<int, int> primes;
for(int i=2;i<=x/i;i++)
while (x % i == 0)//说明i是x的质约数
x=x/i;
primes[i]++;//i是质因子,primes[i]是指数
if(x>1) primes[x]++;
//for(auto p:primes) cout<<p.first<<" "<<p.second<<endl;
for(auto p:primes) res=res*(p.second+1);
cout<<res<<endl;
return 0;
蓝桥杯Web第十四届蓝桥杯Web模拟赛 3 期 | 精品题解(上)
🧑💼 个人简介:一个不甘平庸的平凡人🍬
🖥️ 蓝桥杯专栏:蓝桥杯题解/感悟
🖥️ TS知识总结:十万字TS知识点总结
👉 你的一键三连是我更新的最大动力❤️!
📢 欢迎私信博主加入前端交流群🌹
📑 目录
- 🔽 前言
- 1️⃣ 网页PPT
- 2️⃣ 西游记之西天取经
- 3️⃣ 商品销量和销售额实时展示看板
- 4️⃣ 蓝桥校园一卡通
- 5️⃣ 会员权益领取中心
- 6️⃣ 心愿便利贴
- 7️⃣ 消失的 Token
- 8️⃣ 封装 Promisefy 函数
- 🔼 结语
🔽 前言
好久没更新了,今天上线收到了很多小伙伴的私信,发现有很多朋友正在准备蓝桥杯,问我要不要出几天前开放的模拟赛 3 期的解析,其实这一期的模拟赛刚开始时我就知道了,但根据以往CSDN平台的限制以及我确实没想到会有这么多人想看,于是就没第一时间出。
看到了大家的催更后,我想着就发一下试试吧,希望能顺利发出,话不多说,开干!
由于篇幅有限,这次题解将分为上下两篇,这一篇先讲本科组的前八题,下一篇中我们再讲本科组的最后两题和职业院校组中和本科组不一样的题。
1️⃣ 网页PPT
使用简单的JQuery
就能实习:
function switchPage()
// TODO: 请补充该函数,实现根据activeIndex切换页面的功能,并且在到达最后一页或第一页时给相应的按钮添加disable类
// 1. 设置指定页面显示
$("section").each((index, item) =>
$(item).css("display", index !== activeIndex ? "none" : "block");
);
// 2. 修改页码
$(".controls .page").text(`$activeIndex + 1 / 5`);
// 3. 根据情况修改按钮的class
if (activeIndex === 0)
$(".btn.left").addClass("disable");
else if (activeIndex === sectionsCount - 1)
$(".btn.right").addClass("disable");
else
$(".btn.left").removeClass("disable");
$(".btn.right").removeClass("disable");
2️⃣ 西游记之西天取经
考察CSS3
动画属性,题目中说动画只动一次就会停下来,这明显是没有设置动画的animation-iteration-count
(动画执行次数)导致的,所以想要让动画无限循环起来,只需要为每个animation
复合属性添加infinite
(无限循环)即可:
/* TODO 填空 */
animation: a3 0.8s steps(8) infinite ;
3️⃣ 商品销量和销售额实时展示看板
考查echarts
的基础使用,挺简单的,直接上代码:
// TODO:补全 `yAxis` 的设置,要求“销售额”(即,配置项 `name`)的位置(即,配置项 `position`)在图表的左侧,“销量”(即,配置项 `name`)的位置(即,配置项 `position`)在图表的右侧。
yAxis: [
type: 'value',
name: '销售额',
position: 'left',
,
type: 'value',
name: '销量',
position: 'right',
],
// TODO:补全代码,正确给 X 轴的时间,以及 Y 轴的商品的销售额 saleObj 和销量赋值 countObj。
charData.xAxis.data = Object.keys(result.data.countObj); // 获得由全部key组成的数组
charData.series[0].data = Object.values(result.data.saleObj); // 获得由全部value组成的数组
charData.series[1].data = Object.values(result.data.countObj);
4️⃣ 蓝桥校园一卡通
考察一些简单的正则与表单验证,这里我封装了一个validate
函数专门用来验证输入与控制DOM
:
submit.onclick = () =>
// TODO 待补充代码
/**
* 用于验证输入并控制相关DOM操作
* @param RegExp reg 用于检验文本的正则
* @param Element inputNode input元素
* @param String parentNodeClass 需要给父节点添加的类名
* @param String errorNodeId 错误信息节点的id
* @return *
*/
function validate(reg, inputNode, parentClass, errorId)
const parentElement = inputNode.parentElement // 获取父元素
const errorElement = parentElement.querySelector('#' + errorId) // 获取错误信息元素
let result = false // 是否通过验证
if (!reg.test(inputNode.value))
// 输入不匹配
parentElement.classList.add(parentClass) // 给父节点添加class
errorElement.style.display = 'block' // 显示错误信息
else
// 输入匹配
parentElement.classList.remove(parentClass) // 移除父节点class
errorElement.style.display = 'none' // 隐藏错误信息
result = true
return result
// 姓名
let regName = /^[\\u4e00-\\u9fa5]2,4$/g
const nameVail = validate(regName, studentName, 'has-error', 'vail_name')
if (!nameVail)
return
// 学号
let regStuId = /^\\d1,12$/g
const stuIdVail = validate(regStuId, studentId, 'has-error', 'vail_studentId')
if (!stuIdVail)
return
item[0].innerHTML = studentName.value
item[1].innerHTML = studentId.value
item[2].innerHTML = college.value
// 添加 showCard 类显示放大一卡通的动画,请勿删除
cardStyle.classList.add('showCard')
5️⃣ 会员权益领取中心
每次蓝桥杯的题中都会有一道这种仿页面的题,没啥技术含量,就是纯体力活,这里就不贴代码了。大家在考试的时候切记不要浪费太多时间在这道题上,很容易吃力不讨好。
6️⃣ 心愿便利贴
这题主要考察了element-ui
表单验证,根据代码中的提示发现有两处需要修改。
一是,题中给出的代码中v-for
遍历的是一个空数组v-for="(item,index) in []"
,我们需要找到存放数据的数据来替换这个空数组,翻到下面的提交方法onSubmit
中很容易发现数据存放在wishList
中,所以:
<!-- TODO 待修改的代码 -->
<div class="card" :class="item.css" v-for="(item,index) in wishList" ...
二是,需要补充rules
中的验证规则:
rules:
// TODO 待补充验证的代码
name: [
required: true, message: '请输入姓名', trigger: 'blur' ,
min: 2, max: 4, message: '长度在 2 到 4 个字符', trigger: 'blur'
],
content: [
required: true, message: '请输入许愿内容', trigger: 'blur' ,
min: 1, max: 30, message: '长度在 1 到 30 个字符', trigger: 'blur'
],
,
每条规则的key
对应的是el-form-item
上的prop
属性,根据题目的示例,这两天规则很容易写出,这里就不多说了。
7️⃣ 消失的 Token
考察Vuex
的使用,题目中明确说了:“仔细阅读 store
文件夹下的相关代码并结合 Vuex
相关知识,排查代码中存在的问题”。
所以我们应该先去看一下Vuex
相关的代码,在UserModule.js
中会发现UserModule
这个模块开启了命名空间:
UserModule.js
const UserModule =
namespaced: true, // 开启了命名空间
...
index.js
中是通过user
字段来引入UserModule
的:
index.js
const store = new Vuex.Store(
modules:
base: BaseModule,
user: UserModule, // 注意
,
)
所以在使用UserModule
模块的内容时就需要注意要通过命名空间user
来引用,之后检查index.html
就很容易发现问题所在了:
// TODO 修改下面错误代码
var app = new Vue(
el: '#app',
data() ,
computed:
welcome()
return store.getters.welcome
,
username()
return store.getters['user/username'] // 修改处:通过命名空间引用
,
token()
return store.getters['user/token'] // 修改处:通过命名空间引用
,
methods:
// 回车/点击确认的回调事件
login(username)
// 修改处:通过命名空间引用
username && store.commit('user/login', username, token: 'sxgWKnLADfS8hUxbiMWyb' )
username && store.commit('say', '登录成功,欢迎你回来!')
)
8️⃣ 封装 Promisefy 函数
考查了promise
的使用,在题中我们很容易发现promisefy
有以下几个需求:
- 需要返回一个函数,并且返回的这个函数还需要返回一个
promise
promisefy
接收的fn
参数是个函数,它最后一个参数是个回调函数,回调函数的第一个参数代表err
信息,第二个参数代表成功返回的结果。
代码:
const promisefy = (fn) =>
// TODO 此处完成该函数的封装
return (...arg) => // 使用剩余参数arg收集所传递的实参
return new Promise((resolve, reject) =>
// 将arg解构传递给fn
fn(...arg, (err, contrast) =>
if (err)
// err存在代表fn运行出错了,调用reject将promise的状态转换为rejected并传递err,此时该promise的catch方法将捕捉到该err错误
reject(err)
// 如果代码运行到这说明没出错,调用resolve将promise的状态转换为fulfilled并传递contrast,此时该promise的then方法将捕捉到该contrast信息
resolve(contrast)
)
)
上面代码也挺简单的,需要注意的一点就是promise
的状态一旦改变就不能再次改变了,所以上面代码中如果先调用了reject
,则后面的resolve
调用就不再起作用了,所以在if
语句中不需要加return
来阻断后续代码的执行。
🔼 结语
距离第十四届蓝桥杯的正式比赛还有不到一个月的时间,好好复习,祝大家都能在正式比赛中取得满意的成绩!
如果本篇文章对你有所帮助,还请客官一件四连!❤️
以上是关于蓝桥杯高频知识点(上)的主要内容,如果未能解决你的问题,请参考以下文章