美文网首页
批量请求

批量请求

作者: peerben | 来源:发表于2019-05-31 12:24 被阅读0次
9881559271729_.pic_hd.jpg

请实现如下函数, 可以批量请求数据, 所有的URL在地址urls参数中, 同时可以通过max参数控制请求的并发度, 当所有请求结束, 需要执行callback回调函数, 发请求的函数使用fetch即可.
function sendRequest(urls: string[], max: number, callback: () => void) {};

题目比较粗糙, 请求发送就结束了, 对返回的数据并没有要求保存

用两种方式实现了一下, 明显async方式可读性更高, 逻辑更清晰, 如果异步请求不用async, 需要在异步的回调中再对自身进行调用

const mapUrlList = (urls: string[]) => urls.map(url => fetch(url));

function sendRequest(urls: string[], max: number, callback: () => void) {
  if (urls.length === 0) {
    callback();
    return;
  }
  
  const reqList = urls.splice(0, max);
  Promise.all(mapUrlList(reqList)).then((respList) => {
    sendRequest(urls, max, callback);
  });
}

async function sendRequest2(urls: string[], max: number, callback: () => void) {

  while(urls.length > 0) {
    const reqList = urls.splice(0, max);
    await Promise.all(mapUrlList(reqList));
  }

  callback();
}
Screen Shot 2019-05-31 at 12.23.54 PM.png

花了心思实现了一版并发密集型的解法, 用promise.all 还是要等最长的请求结束才能进入下一轮, 新的解法能在给定的max-pool计数内并发请求, 如果有1个长多个短的请求, 就很高效, 异步明显在编码上比同步麻烦一些, 思考的维度不一样

enum ReqState {
  Active = 0,
  Progress,
  Done,
}

interface Request {
  url: string,
  state: ReqState
}

// simulate fetch
function doFetch(url: string) {
  return new Promise((resovle, reject) => {
    const wait = Math.floor(Math.random() * 3000);
    setTimeout(() => {
      resovle(`${url} ${repeatRand(10)}`);
    }, wait);
  });
}

function sendRequest3(urls: string[], max: number, callback: () => void) {
  const mapUrl = (url: string): Request => ({url, state: ReqState.Active});
  let reqList = urls.splice(0, max).map(mapUrl);

  function addNewRequest() {
    reqList = reqList.filter(req => req.state != ReqState.Done);
    
    //no new request
    if (urls.length === 0) {
      // no progressing request
      reqList.length === 0 && doOnce(callback);
      return;
    };

    const sub = max - reqList.length;
    const subList = urls.splice(0, sub).map(mapUrl);
    [].push.apply(reqList, subList);

    startRequest(subList);
  }

  function startRequest(urlList: Request[]) {
    urlList.forEach(o => {
      o.state = ReqState.Progress;

      doFetch(o.url).then((resp) => {
        console.log(`req done ${resp}`);
        o.state = ReqState.Done;
        addNewRequest();
      })
    });
  }

  startRequest(reqList);
}

const urls = [
  'www.baidu.com?page=1',
  'www.baidu.com?page=2',
  'www.baidu.com?page=3',
  'www.baidu.com?page=4',
  'www.baidu.com?page=5',
  'www.baidu.com?page=6',
  'www.baidu.com?page=7',
  'www.baidu.com?page=8',
  'www.baidu.com?page=9',
  'www.baidu.com?page=10',
  'www.baidu.com?page=11'
];

sendRequest3(urls, 4, () => {
  console.log(`all requests finished!`);
});
Screen Shot 2019-05-31 at 2.58.18 PM.png

相关文章

  • HBase性能优化-读写性能优化

    查询优化 批量get请求 使用批量请求,可以减少RPC的次数,显著提高吞吐量。批量get请求要么成功返回所有请求数...

  • 批量请求

    请实现如下函数, 可以批量请求数据, 所有的URL在地址urls参数中, 同时可以通过max参数控制请求的并发度,...

  • 第五章 爬虫

    爬虫是指使用代码模拟用户批量发送网络请求,批量获取数据的行为。 axios,是一个基于promise的网络请求库,...

  • 蒸汽登录验证码

    一,批量识别,批量报错 1.提交get请求,使用Json方法获取gid(验证码的身份证明) 注意:请求url中有c...

  • BurpSuite导出log配合SQLMAP批量扫描注入点

    0 sqlmap批量扫描burpsuite请求日志记录 sqlmap可以批量扫描包含有request的日志文件,而...

  • Promise批量请求函数

    // 实现一个批量请求函数 multiRequest(urls, maxNum)

  • Postman读取JSON文件和CSV文件

    在使用postman读取文件前我们先看下使用postman批量执行请求集合 Postman批量执行测试集合 选择要...

  • 使用httpclient 抓包 提交表单 网络请求

    接了个私活,批量注册某app账号,使用fiddler抓包后,多线程批量注册,httpclient的请求工具类源码可...

  • ES _bulk 批量操作用法

    es版本:7.6 es 的 bulk 操作,是用来批量发送请求,或者理解为批量操作的。 支持4种操作 bulk 支...

  • ES 批量操作bulk

    1 介绍 主要介绍批量操作bulk,使用postman进行请求,接口请求的前缀地址统一为elasticsearch...

网友评论

      本文标题:批量请求

      本文链接:https://www.haomeiwen.com/subject/ekdwtctx.html