面试题:设计一个等待函数,等待N时间后执行要做的事情
思路:1. 定时器回调
2. 定时器 + async/await
3. reduce()
4. Promise
实际情景:1秒后输出1,再等待2秒输出2,再等待3秒输出3。
1. 定时器回调
这种方式绝对是最容易想到,但是面试官最不想听的答案。
setTimeout(() => {
console.log(1);
setTimeout(() => {
console.log(2);
setTimeout(() => {
console.log(3);
}, 3000);
}, 2000);
}, 1000);
2. 定时器 + async/await
引入异步调用,显得稍微不俗一点,哈哈。
(async function(){
await setTimeout(() => {
console.log(1);
}, 1000);
await setTimeout(() => {
console.log(2);
}, 2000);
await setTimeout(() => {
console.log(3);
}, 3000);
})()
3. reduce()
利用数组的reduce方法实现,reduce绝对是一个宝藏方法,学起来学起来!
利用一个非常巧的点:1+2 = 3,1+2+3=6。即2正好是1+2=3秒后输出,3正好是1+2+3=6秒后输出。恰巧可以设置出 1,3,6 秒的间隔。
let arr = [1000, 2000, 3000],
i = 0;
/*
reduce(function(total,currentValue,index,arr){},initialValue)
reduce 参数
function(total,currentValue,index,arr) 必需。用于执行每个数组元素的函数。
函数参数:
参数 描述
total 必需。初始值, 或者计算结束后的返回值。
currentValue 必需。当前元素
currentIndex 可选。当前元素的索引
arr 可选。当前元素所属的数组对象。
initialValue 可选。传递给函数的初始值
*/
arr.reduce((n, item) => {
n = n + item; // n为计算结束后返回的值,item为当前值。
setTimeout(() => {
console.log(++i);
}, n);
return n;
}, 0);
4. Promise
function delay(interval = 1000) { // interval 时间
return new Promise(resolve => { // 返回一个Promise,方便链式调用。
let timer = setTimeout(() => {
clearTimeout(timer);
timer = null;
resolve();
}, interval);
});
}
方案一:链式调用 delay
delay(1000).then(() => {
console.log(1);
return delay(2000);
}).then(() => {
console.log(2);
return delay(3000);
}).then(() => {
console.log(3);
});
方案二:利用 async/await 异步执行 delay 方法
(async function () {
await delay(1000);
console.log(1);
await delay(2000);
console.log(2);
await delay(3000);
console.log(3);
})();