上文我们手写了符合Promises/A+的Promise,文章链接在此。由于promise实现篇幅过长,真正面试的时候,反而是ES6中的部分方法的实现更加容易考到(个人愚见)。 手写各个方法的时候要注意入参和返回值,当然更重要的就是此方法实现了什么样的逻辑。关于ES6中promise的方法,在之前文章有整理。可以参考此篇文章来阅读此文。
Promise.prototype.catch
Promise.prototype.catch相当于是.then(null,rejection)。
class Promise{
//....
catch(onRejected){
return this.then(null,onRejected)
}
}
Promise.prototype.finally
class Promise{
//....
finally(onFinally){
onFinally();
return this;
}
}
Promise.resolve
static resolve(value){
if (value instanceof Promise) {
return value;
}
return new Promise((resolve,reject)=>{
resolve(value);
})
}
Promise.reject
static reject(value){
return new Promise((resolve,reject)=>{
reject(value);
})
}
Promise.all
static all(promiseArr){
//返回新的promise实例
return new Promise((resolve,reject)=>{
var length = promiseArr.length
var result = [];
for(var i = 0;i<length;i++){
let _promise = promiseArr[i];
function handlerResolve(index,item){
result[index] = item;
//因为promise完成的时间不尽相同 所以用--length来判断合适全部处理完成
--length;
if(length == 0){
resolve(result);
}
}
Promise.resolve(_promise).then((value)=>{
handlerResolve(i,value);
},reason=>{
//有失败则返回
reject(reason)
return;
})
}
})
}
Promise.race
static race(promiseArr){
return new Promise((resolve,reject)=>{
var length = promiseArr.length
for(var i = 0;i<length;i++){
let _promise = promiseArr[i];
//谁先返回结果就返回谁
Promise.resolve(_promise).then(value=>{
resolve(value)
return;
},reason=>{
reject(reason)
return;
})
}
})
}
Promise.allSettled
static allSettled(promiseArr){
return new Promise((resolve,reject)=>{
var length = promiseArr.length
var result = [];
for(let i = 0;i<length;i++){
let _promise = promiseArr[i];
function handlerResolve(index,item){
result[index] = item;
--length;
if(length == 0){
resolve(result);
}
}
Promise.resolve(_promise).then((value)=>{
handlerResolve(i,{status:'fulfilled',value:value});
},reason=>{
handlerResolve(i,{status:'rejected',reason:reason});
})
}
})
}
请用JS实现Ajax并发请求控制
还有一个常问的问题如下:
实现一个批量请求函数 multiRequest(urls, maxNum),要求如下:
• 要求最大并发数 maxNum
• 每当有一个请求返回,就留下一个空位,可以增加新的请求
• 所有请求完成后,结果按照 urls 里面的顺序依次打出
原文链接在此处 下面我做一个代码的搬运工,实现方法如下:
function multiRequest(urls = [], maxNum) {
// 请求总数量
const len = urls.length;
// 根据请求数量创建一个数组来保存请求的结果
const result = new Array(len).fill(false);
// 当前完成的数量
let count = 0;
return new Promise((resolve, reject) => {
// 请求maxNum个
while (count < maxNum) {
next();
}
function next() {
let current = count++;
// 处理边界条件
if (current >= len) {
// 请求全部完成就将promise置为成功状态, 然后将result作为promise值返回
!result.includes(false) && resolve(result);
return;
}
const url = urls[current];
console.log(`开始 ${current}`, new Date().toLocaleString());
fetch(url)
.then((res) => {
// 保存请求结果
result[current] = res;
console.log(`完成 ${current}`, new Date().toLocaleString());
// 请求没有全部完成, 就递归
if (current < len) {
next();
}
})
.catch((err) => {
console.log(`结束 ${current}`, new Date().toLocaleString());
result[current] = err;
// 请求没有全部完成, 就递归
if (current < len) {
next();
}
});
}
});
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!