[nodejs] Faire des requêtes par lot, en parallèle et avec une pause

Requete par lot

Objectifs

Pouvoir Requêter en masse une API (jusqu’à 30 000 requêtes)

  • en faisant n requêtes en parallèle
  • en donnant la possibilité de créer des lots de requêtes
  • en donnant la possibilité de pouvoir pauser l’envoie des lots

Prérequis

  • nodejs
  • axios pour gérer les requêtes et l’asynchrone
  • async await pour gérer l’asynchrone

 

Le code

La vue

<div> <a id= »btn »>Get all URLS</a> </div> <hr> <div id= »container »></div> <pre id= »result »></pre>

Le style

body { margin: 0; min-height: 100vh; background: #004d4d; } #container > div { width: 150px; margin: 10px; padding: 10px; line-height: 12px; background: #ededed; display: inline-block; border: 2px solid #fff; animation-name: fade-in; animation-fill-mode: both; animation-duration: .3s; } .teal { background: #008080; } .btn-container { margin: 10px; } .card-title { font-size: 14px !important; } @keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }

Le js

Pré-requis:
– crée un package.json en local avec npm init
– installer axios avec npm install axios –save
– coder dans votre fichier nomdefichier.js
– tester le resultat dans le terminal avec $ node nomdefichier.js
– tester le resultat dans le navigateur en ouvrant celui-ci // on importe axios const axios = require(‘axios’); let AllDatas = [], AllDatasInError = [], urls = [], waitTime = 500, // the amount of time we wait between each batch of request start = 0, step = 2, // number of url we request position = 0, nbRequest = 12; // number of request AllDatas[‘total’] = 0; // total of data let btn = document.getElementById(‘btn’); btn.addEventListener(‘click’, function() { batchProcessing(urls); }); function createUrl() { for (let i = 1; i <= nbRequest; i++) { urls.push(https://jsonplaceholder.typicode.com/photos/${i}); } } createUrl(); // timer const waitFor = (ms) => new Promise(r => setTimeout(r, ms)); // parallel REQUEST with AXIOS async function getData(links) { try { const res = await axios.all(links.map(link => axios.get(link))); console.log(‘GetData Start time’, new Date()); return res; } catch (error) { console.log(‘——————————————‘); console.log(error); } } // async function batchProcessing(urls) { const len = urls.length / step; // let result = []; console.time(‘batchProcessing’); console.log(‘batchProcessing Start time’, new Date()); // use of an interceptor to edit every response axios.interceptors.response.use(function (response) { // Do something with response data let responseData = response.data; // const newVal = {}; if (responseData.id) { responseData[‘position’] = ${position}/${len}; // create html element addElement(responseData); AllDatas[‘total’] += 1; AllDatas.push(responseData); } console.log(‘responseData’, responseData); return responseData; }, function (error) { // Do something with response error return Promise.reject(error); }); // batch processing for(let index = 0; index < len; index ++) { var processingUrl = urls.slice(start, start + step); start += step; position += 1; console.log(‘position’, position + ‘ / ‘ + len); console.log(‘processingUrl’, processingUrl); // make the requests const res = await getData(processingUrl); AllDatas = AllDatas.concat(res); // break time await waitFor(waitTime); } // we are now done console.log(‘End timer’, new Date()); console.timeEnd(‘getData’); // console.log(‘Final AllDatas’, AllDatas); // document.querySelector(‘pre’).innerHTML = AllDatas; } /****** RENDERING THE HTML *****/ function addElement (data) { console.log(‘element added’, data); let mainDiv = document.getElementById(« container »); let newDiv = document.createElement(« div »); let newContent = <div> <div> <img src="${data.thumbnailUrl}"> <span> Element ${data.id} </span> </div> <div> <p>${data.title}. (batch ${data.position})</p> </div> <div> <a href="${data.url}">See the source</a> </div> </div>; // console.log(‘newContent’, newContent); newDiv.innerHTML = newContent; mainDiv.appendChild(newDiv); }