# 几个面试常见题

# 事件循环

const p = function () {
  return new Promise((resolve, reject) => {
    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(1);
      }, 0);
      resolve(2);
    });
    p1.then((res) => {
      console.log(res);
    });
    console.log(3);
    resolve(4);
  });
};
p().then((res) => {
  console.log(res);
});
console.log("end");
// 3 end 2 4
// 隐藏 resolve(2) 得到的结果是 3 end 4 1

# 冒泡和捕获

冒泡:自低向上
捕获:自上向下

// 冒泡阶段
window.addEventListener("click", () => {});
// 捕获阶段
window.addEventListener("click", () => {}, true);
  • 平常有哪些场景用到这个机制呢 事件委托
window.addEventListener(
  "click",
  () => {
    if (banned) {
      e.stopPropagation();
    }
  },
  true
);

# 防抖和节流

function throttle(fn, delay) {
  let timer = null;
  let startTime = Date.now();
  return function () {
    let curTime = Date.now();
    let remainning = delay - (curTime - startTime);
    let context = this;
    let args = arguments;
    clearTimeout(timer);
    if (remaining <= 0) {
      fn.apply(context, args);
      startTime = Date.now();
    } else {
      timer = setTimeout(fn, remaining);
    }
  };
}

# Promise

function PromiseAll(promiseArray) {
  return new Promise((resolve, reject) => {
    if (!Array.isArray(promiseArray)) {
      return reject(new Error("传入的参数必须是数组"));
    }
    const res = [];
    const promiseNums = promiseArray.length;
    let counter = 0;
    for (let i = 0; i < promiseNums; i++) {
      Promise.resolve(promiseArray[i])
        .then((value) => {
          counter++;
          res[i] = value;
          if (counter == promiseNums) {
            resolve(res);
          }
        })
        .catch((e) => reject(e));
    }
  });
}
const pro1 = new Promise((res, rej) => {
  setTimeout(() => {
    setTimeout(() => {
      res("1");
      tc;
    }, 1000);
  });
});
const pro2 = new Promise((res, rej) => {
  setTimeout(() => {
    res("2");
  }, 2000);
});
const pro3 = new Promise((res, rej) => {
  setTimeout(() => {
    res("3");
  }, 3000);
});
var res = async () => {
  const k = await PromiseAll([pro1, pro2, pro3]);
  console.log(k);
};
res();
  • cache
const cacheMap = new Map();
function enableCachee(target, name, descriptor) {
  const val = descriptor.value;
  descriptor.value = async function (...args) {
    const cacheKey = name + JSON.stringify(args);
    if (!cacheMap.get(cacheKey)) {
      const cacheValue = Promisee.resolve(val.apply(this, args)).catch((_) => {
        cacheMap.set(cacheKey, null);
      });
      cacheMap.set(cacheKey, cacheValue);
    }
    return cacheMap.get(cachKey);
  };
  return descriptor;
}

class PromiseClass {
  @enableCache
  static async getInfo() {}
}
// PromiseClass.getInfo();
// PromiseClass.getInfo();
// PromiseClass.getInfo();
// PromiseClass.getInfo();
// PromiseClass.getInfo();

# 算法

  • 接雨水
// 栈
var trap = function (height) {
  console.log(height.length);
  let sum = 0,
    stack = [],
    i = 0;
  while (i < height.length) {
    while (stack.length && height[i] > height[stack[stack.length - 1]]) {
      let top = stack.pop();
      console.log(i, ":", stack);
      if (!stack.length) break;
      // 计算
      let width = i - stack[stack.length - 1] - 1;
      let minHeight =
        Math.min(height[stack[stack.length - 1]], height[i]) - height[top];
      sum += width * minHeight;
    }
    stack.push(i++);
  }
  return sum;
};
console.log(trap([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]));