nodejs批量发起请求的问题

我利用nodejs在,批量请求一个接口并处理返回的数据。先要从excel里读取1000个身份证,然后通过请求接口得到返回数据,全部请求完后,将返回的数据存入excel并导出。现在我想问怎么批量请求1000次,最快?请求用的是superagent插件。我的语句里面有很多promise的方法,对应的不同接口,要求是每个身份证都跑一遍接口,获得的数据根据身份证统一整理

const superagent = require('superagent');
const exceljs = require('exceljs');

function getData1(id) {
return new Promise((resolve, reject) => {
superagent
.get(https://example.com/api/data1/${id})
.then(res => {
resolve(res.body);
})
.catch(err => {
reject(err);
});
});
}

function getData2(id) {
return new Promise((resolve, reject) => {
superagent
.get(https://example.com/api/data2/${id})
.then(res => {
resolve(res.body);
})
.catch(err => {
reject(err);
});
});
}

function getData3(id) {
return new Promise((resolve, reject) => {
superagent
.get(https://example.com/api/data3/${id})
.then(res => {
resolve(res.body);
})
.catch(err => {
reject(err);
});
});
}

async function processBatch(ids, startIndex) {
// 为每个身份证号码发送请求
const data = await Promise.all(
ids
.slice(startIndex, startIndex + 10)
.map(async id => {
const [data1, data2, data3] = await Promise.all([
getData1(id),
getData2(id),
getData3(id)
]);
    return {
      id,
      data1,
      data2,
      data3
    };
  })
);

// 将数据写入 Excel
data.forEach(d => {
sheet.addRow([d.id, d.data1, d.data2, d.data3]);
});
}

async function main() {
const workbook = new exceljs.Workbook();
const sheet = workbook.addWorksheet('Sheet 1');

// 读取 Excel 文件中的身份证号码
const ids = // ...

let startIndex = 0;
while (startIndex < ids.length) {
await processBatch(ids, startIndex);
startIndex += 10;
}

await workbook.xlsx.writeFile('output.xlsx');
}

main();

如果有用的话请点击采纳

const axios = require('axios').default
// 每一批要发送多少条数据
const BATCH_SIZE = 10
// 生成100条数据,自己把这里替换成你的那些
const mArray = new Array(100).fill('11111111111111111')
// 答主的需求,每10个一批发送
for (let i = 0; i < mArray.length; i+=BATCH_SIZE) {
  const mTemp = mArray.slice(i, i + 10)
  // 里头的接口自己替换,使用promise.all一次性直接发送10次
  Promise
  .all(mTemp.map(id => axios.get(`https://这里替换成你的接口?id=${id}`)))
  .then(res => {
    // 这个res是个数组,一次性拿到10个返回数据
    console.log(res)
  })
}

按着答主的需求写了一份例子,里头的接口地址需要自行修改,使用了axios来请求,写起来相对优越
答主的需求如下

  1. 可以自行更改发送批次
  2. 完成按批次来一次性发送单批次的多条请求

可以 考虑使用Node.js中的Promise.all,它可以帮助您一次性发出所有1000个请求,同时等待服务器响应,然后处理返回的数据。还可以使用Async/Await函数来管理多个异步请求,这样可以有效地降低请求的响应时间。

1、使用async/await

使用async/await可以轻松地实现批量发起请求。使用async/await可以实现并发请求,而不是顺序请求。

示例代码:

const axios = require('axios');

async function makeRequests(){
  const requests = [
    axios.get('http://example.com/api/1'),
    axios.get('http://example.com/api/2'),
    axios.get('http://example.com/api/3')
  ];

  const results = await Promise.all(requests);

  console.log(results);
}

makeRequests();

2、使用Promise.all

使用Promise.all可以实现批量发起请求。Promise.all接受一个数组,该数组中的每个元素都是一个Promise实例,当所有的Promise实例都完成时,Promise.all返回一个新的Promise实例,并且这个新的Promise实例的结果就是所有Promise实例的结果的数组。

示例代码:

const axios = require('axios');

function makeRequests(){
  const requests = [
    axios.get('http://example.com/api/1'),
    axios.get('http://example.com/api/2'),
    axios.get('http://example.com/api/3')
  ];

  Promise.all(requests)
    .then(results => {
      console.log(results);
    })
    .catch(err => {
      console.error(err);
    });
}

makeRequests();

1、可以使用async/await,将请求接口的操作封装成一个函数,然后使用for循环将1000个身份证一个一个传入函数中,并使用Promise.all()方法一次性发出所有的请求,最后等待所有的请求返回结果,并将结果存入excel中。

2、可以使用superagent提供的.parallel()方法,将1000个身份证一次性发出请求,并等待所有的请求返回结果,将结果存入excel中。

3、也可以使用nodejs的cluster模块,将1000个身份证拆分成多个子任务,并在多个进程中并行处理,最后将结果存入excel中。

方法一


,存入excel表里(每个身份证是一行)

可以使用async/await 来实现批量请求1000次。代码如下:

const fs = require('fs'); 
const exceljs = require('exceljs'); 
const superagent = require('superagent'); 

// 读取excel里的1000个身份证
const readExcel = async () => {
    let data = []; 
    const workbook = new Excel.Workbook();
    await workbook.xlsx.readFile('./ids.xlsx'); 
    const worksheet = workbook.getWorksheet(1);
    worksheet.eachRow(row => {
        data.push(row.getCell(1).value);
    });
    return data;
}

// 请求接口,获取返回数据
const requestData = async (ids) => {
    let results = []; 

    for(let i = 0; i < ids.length; i++) {
        // 并发请求接口
        results.push(await superagent
            .get(`http://xxxx/api?id=${ids[i]}`))
    }
    return results;
}

// 将获取的数据保存到excel中
const saveToExcel = async (data) => {
    let workbook = new Excel.Workbook();
    workbook.xlsx.writeFile('./result.xlsx');
    let worksheet = workbook.addWorksheet('sheet1');
    worksheet.columns = [{
        header: '身份证号',
        key: 'id'
    }, {
        header: '返回数据',
        key: 'return_data'
    }]
    await worksheet.addRows(data);
}

(async () => {
    const ids = await readExcel();
    const data = await requestData(ids);
    await saveToExcel(data);
})()

方法二



//引入excel文件 
const ExcelData = require('ExcelFile');

//获取1000个身份证
let idCards = ExcelData.getIdCards();

//使用async/await 的方式,批量请求
let requestPromises = idCards.map(async (idCard) => {
    let res = await superagent('url', {
        method:'post',
        data:{
            idCard
        }
    });
    return res;
});

//Promise.all()等待所有请求完成
try {
   let responses = await Promise.all(requestPromises);
   //将返回的数据存入excel并导出 
   ExcelData.saveResponsesToExcel(responses);
} catch (err){
   console.log(err);
}

方法一

入一个excel文件

  1. 使用async & await语句,对每个身份证发起请求,等待返回结果。
  2. 使用promise.all()方法,批量发起请求,等待所有请求结束后再处理。
  3. 使用nodejs的events模块,分批次发起请求,在每一批请求结束后处理返回数据并写入excel文件。
const fs = require('fs');

let line = 0; //当前处理到第几行 1~n
let jobs = 10; //同时并行执行任务数量 
let result = {}; //结果数据  key=身份证号 value={data1,data2,data3}

//导出结果
function saveResult(){
    let csvdata = "身份证号,数据项1,数据项2,数据项3\n";
    for(let key in result){
        let obj = result[key];
        csvdata += `${key},${obj.data1},${obj.data2},${obj.data3}\n`;
    }
    fs.writeFileSync("output.csv", csvdata);
}

//读取第n行的身份证id (line从1开始,超出返回null) (这里模拟实现,改成你实际需要的)
function readId(line){
    if(line > 25)return null;
    return "id_" + line;
}

//HTTP请求获取数据(url地址,返回JSON数据的key) (这里模拟实现,改成你实际需要的)
function request(url, datakey){
    return new Promise((resolve,reject)=>{ 
        let data = Math.round(Math.random() * 2000); 
        setTimeout(()=>{ resolve(data);}, data);
    });    
}

//执行单个身份证的数据处理   (这里模拟实现,改成你实际需要的)
async function runOnce(id){
    let obj = {}; 
    console.log(`request ${id}`);   
    obj.data1 = await request("http://xxx/1", "data1");
    obj.data2 = await request("http://xxx/2", "data2");
    obj.data3 = await request("http://xxx/3", "data3");
    console.log(`request ${id} finish`);   
    result[id] = obj;
    runNext();
}   

//执行下一个ID
function runNext(){
    line ++;
    let id = readId(line);
    if(id){ 
        runOnce(id);
    }else{ //一个并行任务结束
        jobs --;
        if(jobs == 0){ //全部并行任务结束
            saveResult();
            console.log("finish");
        }
    }    
}

//N个任务并行执行
for(let i=0;i<jobs; i++){
    runNext();
}

是否可以实用vue中的组件实现导入导出的需求,主要是处理数据调用接口的时候建议分批次处理 最终拿到数据后在进行组装数据和导出

你可以使用Node.js中的HTTP模块的request函数或 Axios 库来快速发起HTTP请求,可以使用async/await或Promise来完成批量发起请求的操作。
你可以使用这个实例代码来发起HTTP请求:

const axios = require('axios');
const urls = ['URL1', 'URL2', ...];

Promise.all(urls.map(url => {
  return axios.get(url);
}))
.then(res => {
  // Do something with the response
})
.catch(err => {
  // Handle errors
});
不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^