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 class="btn-container"> <a id="btn" class="waves-effect waves-light 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 class="card">
<div class="card-image">
<img src="${data.thumbnailUrl}">
<span class="card-title">
Element ${data.id}
</span>
</div>
<div class="card-content">
<p>${data.title}. (batch ${data.position})</p>
</div>
<div class="card-action">
<a href="${data.url}">See the source</a>
</div>
</div>`;
// console.log('newContent', newContent);
newDiv.innerHTML = newContent;
mainDiv.appendChild(newDiv);
}

