kangyana / daily-question

When your heart is set on something, you get closer to your goal with each passing day.
https://www.webpack.top
MIT License
3 stars 0 forks source link

【Q141】阿里云笔试 #141

Open kangyana opened 1 year ago

kangyana commented 1 year ago

一面

kangyana commented 1 year ago

1. 使用 promise 实现并发请求限制

有 8 个图片资源的 url,已经存储在数组 urls 中,而且已经有一个函数 loadImages。 要求:

  1. 任意时刻,同时下载的链接数量不可以超过 n 个。
  2. 尽可能快速地将所有图片下载完成。
const urls = [
  "https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg",
  "https://www.kkkk1000.com/images/getImgData/gray.gif",
  "https://www.kkkk1000.com/images/getImgData/Particle.gif",
  "https://www.kkkk1000.com/images/getImgData/arithmetic.png",
  "https://www.kkkk1000.com/images/getImgData/arithmetic2.gif",
  "https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg",
  "https://www.kkkk1000.com/images/getImgData/arithmetic.gif",
  "https://www.kkkk1000.com/images/wxQrCode2.png",
];

function loadImages(urls,limit){}

loadImages(urls, 3);

解析:该题主要考察对 Promise 的使用,重点需要理解 Promise.race()Promise.allSettled() 的用法。

const urls = [
  'https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg',
  'https://www.kkkk1000.com/images/getImgData/gray.gif',
  'https://www.kkkk1000.com/images/getImgData/Particle.gif',
  'https://www.kkkk1000.com/images/getImgData/arithmetic.png',
  'https://www.kkkk1000.com/images/getImgData/arithmetic2.gif',
  'https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg',
  'https://www.kkkk1000.com/images/getImgData/arithmetic.gif',
  'https://www.kkkk1000.com/images/wxQrCode2.png',
];

// 加载单个图片
function loadSingleImg(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = function () {
      console.log(`加载成功:${url}`);
      resolve(url);
    };
    img.onerror = function (err) {
      console.log(`加载失败:${url}`);
      reject(err);
    };
    img.src = url;
  });
}

// 批量加载图片
async function loadImages(urls, limit) {
  const promises = [];
  const queue = urls.splice(0, limit).map((url, index) => {
    const _p = loadSingleImg(url);
    promises.push(_p);
    return _p.then((res) => {
      return [index, res];
    });
  });
  for (const item of urls) {
    const [index] = await Promise.race(queue);
    const _p = loadSingleImg(item);
    promises.push(_p);
    queue[index] = _p.then((res) => {
      return [index, res];
    });
  }

  return Promise.allSettled(promises);
}

// 测试用例
loadImages(urls, 3).then((res) => {
  console.log('批量加载完毕');
});
kangyana commented 1 year ago

2. js补充日期

数据可视化中,很多情况下都会以日期为横坐标,数据为纵坐标展示折线图,但接口下发的数据不一定是连续的。 接口返回如下数据(数据已经按照日期由早到晚排序):

const data = [
{date: '2021-12-25', cnt: 12},
{date: '2021-12-28', cnt: 7},
{date: '2021-12-30', cnt: 9},
{date: '2022-01-02', cnt: 4},
{date: '2022-01-03', cnt: 4}
];

请写一个函数 pathDate()补全缺失的日期数据(默认为0即可),效果如下:


const result = pathDate(data);

// result 结果为: [ {date: '2021-12-25', cnt: 12}, {date: '2021-12-26', cnt: 0}, // 新增 {date: '2021-12-27', cnt: 0}, // 新增 {date: '2021-12-28', cnt: 7}, {date: '2021-12-29', cnt: 0}, // 新增 {date: '2021-12-30', cnt: 9}, {date: '2021-12-31', cnt: 0}, // 新增 {date: '2022-01-01', cnt: 0}, // 新增 {date: '2022-01-02', cnt: 4}, {date: '2022-01-03', cnt: 4} ];


### 解析:该题主要考察对 `Date API` 的运用。
```javascript
const data = [
  { date: '2021-12-25', cnt: 12 },
  { date: '2021-12-28', cnt: 7 },
  { date: '2021-12-30', cnt: 9 },
  { date: '2022-01-02', cnt: 4 },
  { date: '2022-01-03', cnt: 4 },
];

// 补全日期
function pathDate(_date) {
  // 开始时间戳
  const start = data[0].date.replace(/-/g, '/');
  const startTime = +new Date(start);
  // 结束时间戳
  const end = data[data.length - 1].date.replace(/-/g, '/');
  const endTime = +new Date(end);
  // 一天的时间戳
  const dayTime = 86400000;
  // 一共几天
  const step = (endTime - startTime) / dayTime + 1;
  // 时间范围
  let dateRange = [];
  for (let index = 0; index < step; index++) {
    let date = formatDate(startTime + dayTime * index); // 当日时间
    // 旧数据替换,新数据填充
    const findIndex = data.findIndex((item) => item.date === date);
    if (findIndex > -1) {
      dateRange.push(data[findIndex]);
    } else {
      dateRange.push({ date, cnt: 0 });
    }
  }
  return dateRange;
}

// 格式化日期
function formatDate(time) {
  const date = new Date(time);
  const pad = (n) => (n < 10 ? `0${n}` : n);
  const dateStr = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
  return dateStr;
}

// 测试用例
const result = pathDate(data);
console.log(result);