Estoy haciendo un proyecto que actualiza la información de muchos pacientes con axios call. Analicé el archivo csv del paciente en formato JSON. Y llame a la API de publicación para actualizar la información de cada paciente como se muestra a continuación.
/** * this.csvJson.data : List of JSON format, each json contain one patient's information */ . . await this.csvJson.data.map(async (data)=>{ await axios.post(`api/MetaData/${this.projects.projectId}`,data) .then(response=>{ //response handling }) .catch(error=>{ //error handling }) }) . .En este caso, cuando el número de pacientes es inferior a 200, el proceso de carga es comparativamente estable. Pero cuando el número de pacientes supera los 20000, el navegador no responde. Creo que llamar a varias api para cada paciente provoca un bloqueo del navegador.
¿Cuál es la forma correcta de manejar múltiples llamadas api como esta?
Con ese código, está realizando 20000 solicitudes en un instante, no es de extrañar que el navegador se bloquee. dado que ya está utilizando una biblioteca externa, puede echar un vistazo a fastq .
Aquí está mi implementación en React, básicamente fastq puede tomar cada parámetro de cada solicitud y luego envolver cada uno de ellos en una función de trabajador asíncrono, luego solo hará un número de " concurrencia " de solicitud a la vez. Si realiza 20000 solicitudes, dependiendo de qué tan rápido se realicen, tomará tiempo terminar. es posible que desee agregar más simultaneidad para hacerlo más rápido.
import fastq from "fastq"; export async function consecutiveRequest(data, requester, concurrency = 10) { const workerFunction= async (args) => { try { const data = await requester(args.params); console.log(args.index, "Requested:", args, "Result:", data); return data; } catch (error) { console.error(error); return null; } }; const consecutiveQueue = fastq.promise( workerFunction, // fastq take a worker function concurrency // number of requests only allowed at a time ); const req = []; for (let i = 0; i < data.length; i++) { const params = data[i]; req.push(consecutiveQueue.push({ params, index: i })); } let data = await Promise.all(req); return data; } import _ from "lodash"; import React from "react"; import { consecutiveRequest } from "./request"; import "./styles.css"; export default function App() { const randomNumbers = _.range(0, 50).map(() => _.random(0, 4)); const [results, setResults] = React.useState([]); const [loading, setLoading] = React.useState(false); const handleSendQueueRequest = async () => { setLoading(true); const res = await consecutiveRequest( randomNumbers, async (random) => { const url = `https://cat-fact.herokuapp.com/facts`; const res = await fetch(url, { method: "GET" }); const json = await res.json(); const facts = json || []; return facts[random]?.text; }, 10 ); setResults(res); setLoading(false); }; return ( <div className="App"> <button disabled={loading} onClick={handleSendQueueRequest}> {loading ? "Loading" : "Get Random Quote"} </button> <pre>{JSON.stringify(results, null, 2)}</pre> </div> ); }Heres the codesandbox eche un vistazo en la consola para ver cómo funciona.
Para múltiples apiCall, usar Promise.all suele ser una mejor opción, pero no sé si puede manejar 20 000 solicitudes
const promises = csvJsonData.map((patientData) => { return axios.post(`api/MetaData/${this.projects.projectId}`, data); }); Promise.all(promises) .then((response) => { //response handling }) .catch((error) => { //error handling });