阅读 475

promise增加超时;改造promise.all不管参数多个实例的结果成功与否都进入到resolve状态,同时增加超时

说实话,这篇文章的标题我也不知道如何设定更为准确。这两个问题是我最近偷摸面试遇到的,觉得有点意思,所以记录一下,做个分享。

题目一:已知一个promise的实例,如何给这个实例增加超时限时,超时了就返回超时失败。

我们可以先分析一下,如果promise实例执行时间过长,我们要返回超时,那可以用另一个带有时间限时的实例与之比较竞争谁率先改变状态啊,这个可以使用Promise.race解决这个问题,所以咱就直接用这个API实现一下:

let promise1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("成功了");
	},2000)
});
let promise2 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject("超时失败了");
	},1000)
});
Promise.race([promise1,promise2]).then((res) => {
	console.log(res);
}).catch((e) => {
	console.log(e);
});
//超时失败了
复制代码

稍微改造一下:

let promise1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("成功了");
	},2000)
});

function myPromiseTimeOut (promise,time=1000){
	let promiseTimeOut = new Promise((resolve,reject)=>{
		setTimeout(()=>{
			reject("超时失败了");
		},time)
	});
	Promise.race([promise,promiseTimeOut]).then((res) => {
		console.log(res);
	}).catch((e) => {
		console.log(e);
	});
}
myPromiseTimeOut(promise1);
//超时失败了
复制代码

题目一大概的解题方法和思路就是这样的。

题目二:改造promise.all不管参数多个实例的结果成功与否都进入到resolve状态,同时增加超时。

我们可以先分两步解题,首先封装一个promiseAll函数,在函数里遍历promise.all的参数,并执行,在执行每个实例之后把所有结果带入到promiseAll的resolve中。

let promise1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("成功了");
	},2000)
});
let promise2 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject("失败了");
	},1000)
});

function promiseAll(all){
	if(Object.prototype.toString.call(all) !="[object Array]"){
		return Promise.reject("params should be an array")
	}
	let res = [];
	let count = 0;
	return new Promise((resolve,reject)=>{
		for (let i =0; i<all.length;i++){
			Promise.resolve(all[i]).then(result=>{
				count++;
				res[i] = result;
				if(count==all.length){
					return resolve(res)
				}
			}).catch((e) => {
				count++;
				res[i] = e;
				// return reject(e)
				if(count==all.length){
					return resolve(res)
				}
			})
		}
	})
}
promiseAll([promise1,promise2]).then((res) =>{
	console.log("success")
	console.log(res)
}).catch((e) => {
	console.log("fail")
	console.log(e)
})
//success
//["成功了", "失败了"]
复制代码

接下来,就是对paomiseAll进行改造,增加超时限制。

let promise1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("成功了");
	},1000)
});
let promise2 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject("失败了");
	},2000)
});

function promiseAll(all,time=1000){
	if(Object.prototype.toString.call(all) !="[object Array]"){
		return Promise.reject("params should be an array")
	}
	let promiseTimeOut = new Promise((resolve,reject)=>{
		setTimeout(()=>{
			reject("超时了");
		},time)
	});
	let res = [];
	let count = 0;
	return new Promise((resolve,reject)=>{
		for (let i =0; i<all.length;i++){
			Promise.race([all[i],promiseTimeOut]).then(result=>{
			// all[i].then(result=>{
				count++;
				res[i] = result;
				if(count==all.length){
					return resolve(res)
				}
			}).catch((e) => {
				count++;
				res[i] = e;
				// return reject(e)
				if(count==all.length){
					return resolve(res)
				}
			})
		}
	})
}
promiseAll([promise1,promise2]).then((res) =>{
	console.log("success")
	console.log(res)
}).catch((e) => {
	console.log("fail")
	console.log(e)
})
//success
// ["成功了", "超时了"]
复制代码

这两题的思路大概就是这样的。

Time!

文章分类
前端